Akka-Http perf difference chunked vs non-chunked

286 views
Skip to first unread message

daleksan

unread,
May 27, 2016, 5:22:08 AM5/27/16
to Akka User List
Hello,

while evaluating Akka-Http I noticed a significant performance difference between normal and chunked encoding. It is the non-chunked case which is much slower. The difference are significant - 1minute vs 4 seconds for a 10MB message on same HW.

It seems the explanation is really small ByteString sizes of the request entity for the non-chunked case.

My code needs to read the request content into a buffer, for which I am using StreamConverters, but for the investigation purposes I replaced this with an explicit code [1].

For chunked encoding the println statement logs numbers close to the chunk size used by the client e.q. for client using chunks of 1024B it says 1017.

For normal transfer encoding however the message says anything between 1 and 9 bytes all the time, 1-3 most of the time. It seems wrong to use such small buffers. 

Can this perhaps be fixed by configuration?

Thank you

 David

[1]
    // req is the HttpRequest coming from the handler
    val read:Future[ByteArrayOutputStream] = req.entity.dataBytes.runFold(baos)((baos,d)=>{
      val arr = d.toArray
      println(s"reading stream element of ${arr.length} bytes")
      baos.write(arr)
      baos
    })

Akka Team

unread,
May 31, 2016, 7:40:02 AM5/31/16
to Akka User List
Hi David,

I can't repeat this, with non-chunked (which in Akka HTTP becomes a HttpEntity.Default entity) and the latest Akka HTTP I mostly see chunk sizes around 131 072 bytes, which maches up pretty well with the TCP packet sizes for the same request. 
Locally I see response times of 200-300ms PUT:ing a 10mb file using curl, and not a significant difference between chunked and non-chunked.

Can you please give us more details about what you are doing seeing these numbers, what Akka HTTP version, what client you are using, anything else that may be special etc?

--
Johan

Akka Team
Typesafe - Reactive apps on the JVM
Blog: letitcrash.com
Twitter: @akkateam

daleksan

unread,
Jun 1, 2016, 5:05:06 AM6/1/16
to Akka User List
Hello Johan,

thanks for your answer. I have a simple project where the issue can be observed. The project does more - it is an experiment to decouple request processing from their acceptance, but it is a small project so running it should be smooth.

1. extract the Gradle project
2. in one terminal window do ./gradlew clean build runFairServer
3. in second terminal window do ./gradlew runFairClient
4. see what server prints, I have something like this on my Mac [1]
5. force shutdown server - ctrl+c
6. open build.gradle and change the 'false' in the last 'args' list to 'true', this means using chunked encoding
7. repeat from step 2 and observe difference in output 

I'll attach the project as a separate reply or as a private reply as I'm having errors on the server side - trying to skip the attachment now.

Thank you so much for your help!

 David

[1] 

reading stream element of 8 bytes

reading stream element of 8 bytes

reading stream element of 9 bytes

reading stream element of 8 bytes

reading stream element of 9 bytes


Konrad Malawski

unread,
Jun 1, 2016, 5:22:13 AM6/1/16
to akka...@googlegroups.com, daleksan
I don't see the project attached anywhere - could you put it on github instead?
Thanks for prepping a reproducer.

-- 
Konrad `ktoso` Malawski
Akka @ Lightbend
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

daleksan

unread,
Jun 1, 2016, 5:42:04 AM6/1/16
to Akka User List
Apologies for the delay. Project attached. Turns out google won't allow zip attachments containing executables so I had to remove all gradle executables from the project :-(

Thank you

 David 
davida-fairakkahttp.zip

Johan Andrén

unread,
Jun 1, 2016, 2:32:13 PM6/1/16
to Akka User List
I'd recommend you to use wireshark and look at how the JDK http client you are using actually is sending the data, also, let us know if you can get the same result but using other http clients. curl and wget comes to mind.

--
Johan

daleksan

unread,
Jun 3, 2016, 5:21:02 AM6/3/16
to Akka User List
I can confirm that changing the HTTP client to curl does fix the issue. I can see much bigger buffers used in this case.

This answers my question however I would say Akka-Http still should be guarded from such case (i.e. never emit such small buffers, due to profound performance degradation, no matter how client is sending the data).  

Thank you so much for you help!

 David


Konrad Malawski

unread,
Jun 3, 2016, 5:22:26 AM6/3/16
to akka...@googlegroups.com, daleksan
Right we have a ticket that sounds rather similar I believe (auto toStricting up unto a given limit), I agree it's a good idea.

-- 
Konrad `ktoso` Malawski
Akka @ Lightbend

Reply all
Reply to author
Forward
0 new messages