Comparing Retrofit 2.0 vs. Volley

Executive summary: Retrofit 2 and Volley are both great networking libraries for modern Android apps, but each has its own strengths that are worth weighing for critical projects. Use Retrofit if your use-case is a standard REST API with JSON responses and not too many custom requirements in terms of caching, request prioritization, retries, etc. Use Volley if you have unusual / fine-grained requirements, or if you anticipate needing a lot of flexibility from your networking layer in the future at the cost of more code. Use neither if you're downloading large files or streaming -- for that, use DownloadManager instead.

As Android developers we have 2 great networking libraries available to us: Square's Retrofit and Google's Volley. Naturally, when we have 2 equally good-looking choices we want to take the right decision -- based on actual use-cases and anticipated growth of our apps in the future. In particular, I would recommend not selecting based on how many boxes these libraries check off on a list of arbitrary features; instead focus on what you really need and choose the one that provides the most robust support for those.

I've used Retrofit extensively for a year and Volley in a somewhat limited way a few months after it was released, so I think I have something to offer in terms of the comparison here. This article is targeted at someone completely new to these libraries. I will not focus too much on how to go about using these libraries, since that is covered well elsewhere. I have however linked to sample code / documentation throughout, so you can use this post as an index.

The details here are updated as of December 2015. Please leave a comment if you find any factual errors / critical omissions, especially about Volley.


Retrofit is dead-simple to use. It essentially lets you treat API calls as simple Java method calls, so you only define which URLs to hit and the types of the request/response parameters as Java classes. The entire network call + JSON/XML parsing is completely handled by it (with help from Gson for JSON parsing), along with support for arbitrary formats with pluggable serialization / deserialization. Documentation is great and the community is huge. I'll just paste some code here so you get a feel for what I'm talking about.

// Retrofit turns your HTTP API into a Java interface
public interface GitHubService {
  Call<List<Repo>> listRepos(@Path("user") String user);

// the Retrofit class generates an implementation of the above interface
Retrofit retrofit = new Retrofit.Builder()
GitHubService service = retrofit.create(GitHubService.class);

// each Call from the created GitHubService can make a synchronous or
// asynchronous HTTP request to the remote webserver
Call<List<Repo>> repos = service.listRepos("octocat");
// let's use the Call asynchronously
call.enqueue(new Callback<List<Contributor>>() {
  @Override void onResponse(Response<List<Contributor>> contributors) {
    // ...

  @Override void onFailure(Throwable t) {
    // ...

Volley involves a little more boilerplate in general. Out-of-the-box, the only response types supported are String, Image, JSONObject, and JSONArray. To avoid the burden of unpacking JSONObjects yourself and use it like Retrofit, you need to include this GsonRequest<T> class, which basically represents a request whose response is converted to type T by Gson. There is also no built-in XML support, but I expect you can build that yourself too. Official documentation on Volley is somewhat lacking, although there are a few basic tutorials by Google, unofficial Javadocs, and a large, scattered body of knowledge over on StackOverflow. Here's a short code sample (note: this is for a raw String response; if you want a response of arbitrary type, like List<Contributor> in the Retrofit example, you'll need to implement GsonRequest<T> yourself):

// instantiate the RequestQueue
RequestQueue queue = Volley.newRequestQueue(this);
String url ="";

// request a string response asynchronously from the provided URL
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
    public void onResponse(String response) {
        // ...
}, new Response.ErrorListener() {
    public void onErrorResponse(VolleyError error) {
        // ...

// add the request to the RequestQueue

Both Retrofit and Volley support async requests with minimal code, as we saw above, so they're equally great there. No more AsyncTasks + manual JSON parsing -- which is a huge win for the maintainability of your code!

Image loading

Retrofit does not come with support for loading images from the network by itself. Another small library called Picasso is recommended for this. I really don't consider this a drawback because (a) Picasso is just as easy to use as Retrofit, and, (b) it avoids over-burdening the core library and bloating your APK if you don't need image loading features -- indeed this might be considered an advantage if you're looking for a smaller library over ease-of-use for images.

Volley has rudimentary support for image loading, which suffices for use-cases with a small number of images and not too many feature requirements. For most non-trivial cases, however, you'll want to use Glide instead.

So in this category it really comes down to Picasso vs Glide. Both libraries have a nearly identical API and feature set. The main differences are that:

Performance and caching

Both libraries use thread pools and execute multiple requests in parallel, and both support the venerable OkHttp library[1].

Retrofit: caching should "just work" if your server sets the correct cache control headers. If not, or if you're trying to do something unusual, you may be out of luck. The only lever you can turn here is your HTTP client layer (OkHttp, HttpUrlConnection, etc), as in this example.

Volley definitely has a more elaborate and flexible caching mechanism. Glide leverages it to great effect for caching bitmaps.

Request prioritization, cancellation and retrying

Retrofit: does not support setting priority, although there are hacks available; supports cancellation since v2 (which is in late beta now); supports manual request retries.

Volley: supports prioritization with a little extra code; supports cancellation and customizable retry with exponential backoff out-of-the-box.

POST requests + multipart uploads

Retrofit has full support for POST requests and multipart file uploads, with a sweet API to boot.

Volley supports POST requests but you'll have to convert your Java objects to JSONObjects yourself (e.g., with Gson). Also supports multipart requests but you need to add these additional classes or equivalent. The experience is not as polished as with Retrofit, but probably a bit more flexible as a result.


Retrofit has a well-designed, intuitive API with a small number of extension points for common use-cases, e.g., for (de)serialization and request threading. Jake Wharton discusses Retrofit 2's extension points in his great talk from Droidcon NYC 2015.

Volley on the other hand is very open to extension and even relies on that fact for common features like request priority, setting up a global long-lived RequestQueue, and bitmap caching. The success of Glide is proof of Volley's great extensibility.

Dynamic URLs

Retrofit supports dynamic URLs since v2. By "dynamic" I mean the URL is not known until runtime, as is the case with pagination in Github's API, which sends previous/next page links in the response headers and the URLs can be unguessable.

Volley obviously supports dynamic URLs, as we saw in the very first example above, the URL being the second parameter in the StringRequest constructor.

Large file downloads / streaming

Neither Retrofit nor Volley is designed for this, and you will probably run into out-of-memory issues if you try. Both recommend using DownloadManager instead, which supports resuming and progress notifications.

  1. OkHttp is a low-level HTTP client library with a boatload of features and great flexibility. Since Android 4.4, it's also the default engine underpinning Android's HttpUrlConnection. ↩︎