Skip to content
This repository has been archived by the owner before Nov 9, 2022. It is now read-only.


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Maven Central License


A small library for composing asynchronous code. The main reason for it to exist is to make it easier to create graphs of interconnected asynchronous calls, pushing the 'worrying about concurrency' aspects into the framework rather than mixing it in with the business logic.

NOTE: this project is no longer supported. Feel free to fork it if you like it. Internally, we've switched to using CompletionStage/CompletableFuture instead.

When should I use it?

  • When you are combining more than 2 asynchronous calls together, and you think the code is hard to read.
  • When you want to separate concurrency management aspects (when code does something) from business logic (what it does).
  • When you want to use something smaller and easier to learn than frameworks like Akka and RxJava.

Probably none of the above, see note at top.

Getting Started

Include the latest version of Trickle into your project:


Define the input parameters to your call graph:

public static final Input<String> KEYWORD = Input.named("keyword");
public static final Input<String> ARTIST = Input.named("artist");

Define the code to be executed in the nodes of your graph:

Func1<String, List<Track>> findTracks = new Func1<String, List<Track>>() {
  public ListenableFuture<List<Track>> run(String keyword) {
    return search.findTracks(keyword);
Func1<String, Artist> findArtist = new Func1<String, Artist>() {
  public ListenableFuture<Artist> run(String artistName) {
    return metadata.lookupArtist(artistName);
Func2<Artist, List<Track>, MyOutput> combine = new Func2<Artist, List<Track>, MyOutput>() {
  public ListenableFuture<MyOutput> run(Artist artist, List<Track> tracks) {
    return Futures.immediateFuture(new MyOutput(artist, tracks));

Wire up your call graph:

Graph<List<Track>> tracks =;
Graph<Artist> artist =;
this.output =, tracks);

Note that the findTracks node has been given a fallback, so an empty list of tracks will be used if the call to find tracks throws an exception. This way, you can get graceful degradation in case of partial failure.

At some later stage, call the graph for some specific keyword and artist name:

public ListenableFuture<MyOutput> doTheThing(String keyword, String artistName) {
  return this.output.bind(KEYWORD, keyword).bind(ARTIST, artistName).run();

See for more examples and see the wiki for more in-depth descriptions of the library.

Notes about maturity

We're using Trickle internally at Spotify in core, production-critical services that would break Spotify completely if they failed. This means we have a fairly high degree of confidence that it works. It is, however, a young library and you shouldn't be surprised if there are API changes in the next few months.

Code of conduct

This project adheres to the Open Code of Conduct. By participating, you are expected to honor this code.


A small library for composing asynchronous code



Code of conduct





No packages published