Django REST Framework - POST slowness when body size greater than 1024 characters











up vote
2
down vote

favorite
2












I'm using DRF. I found that receiving a POST with more than 1024 characters causes a ~1 second penalty, while anything less than that is effectively free. I've simplified this into this trivial example:



# views.py
import time
from rest_framework.decorators import api_view
from django.http import HttpResponse

@api_view(['POST'])
def test_endpoint(request):

t = time.time()
data = request.body
total_time = time.time() - t

print('got post data:', round(total_time, 3))
return HttpResponse('body size:{} time:{}'.format(len(data), round(total_time, 3)))


# url.py
urlpatterns = [
url(r'^test_endpoint', test_endpoint),
]


You can see that all I'm doing is reading the request.body and measuring the time it takes to do so. Then I respond with that time, and the len of the request.body (to prove I accessed it).



Then I execute these curls:



$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 0123456782345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567901234567890123456789012345678901234567
body size:1024 time:0.0
real 0m0.045s
user 0m0.006s
sys 0m0.009s
$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 01234567823456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567890123456789012345678
body size:1025 time:0.999
real 0m1.020s
user 0m0.006s
sys 0m0.006s


You can see the second one has one extra character, and that causes a ~1 second penalty to ready request.body.



Why is that? How can I prevent this?



More Info



I made this as vanilla as I could. I created an new project with django-admin startproject helloworld_project .. I put the code above into it. And running it locally with python manage.py runserver. I don't have a webserver in front of it; I'm accessing it directly with my browser. That's all I'm doing.



Also, I'm doing this on Django==1.11. This problem seems to go away on Django==2.0. I cannot easily upgrade to 2.0. Is there a workaround for this issue on 1.11?










share|improve this question
























  • what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
    – Satevg
    10 hours ago










  • Same results with werkzeug. Probably additional information needed on how your app being deployed.
    – Satevg
    9 hours ago










  • I added more info about my setup above.
    – Landon
    3 hours ago















up vote
2
down vote

favorite
2












I'm using DRF. I found that receiving a POST with more than 1024 characters causes a ~1 second penalty, while anything less than that is effectively free. I've simplified this into this trivial example:



# views.py
import time
from rest_framework.decorators import api_view
from django.http import HttpResponse

@api_view(['POST'])
def test_endpoint(request):

t = time.time()
data = request.body
total_time = time.time() - t

print('got post data:', round(total_time, 3))
return HttpResponse('body size:{} time:{}'.format(len(data), round(total_time, 3)))


# url.py
urlpatterns = [
url(r'^test_endpoint', test_endpoint),
]


You can see that all I'm doing is reading the request.body and measuring the time it takes to do so. Then I respond with that time, and the len of the request.body (to prove I accessed it).



Then I execute these curls:



$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 0123456782345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567901234567890123456789012345678901234567
body size:1024 time:0.0
real 0m0.045s
user 0m0.006s
sys 0m0.009s
$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 01234567823456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567890123456789012345678
body size:1025 time:0.999
real 0m1.020s
user 0m0.006s
sys 0m0.006s


You can see the second one has one extra character, and that causes a ~1 second penalty to ready request.body.



Why is that? How can I prevent this?



More Info



I made this as vanilla as I could. I created an new project with django-admin startproject helloworld_project .. I put the code above into it. And running it locally with python manage.py runserver. I don't have a webserver in front of it; I'm accessing it directly with my browser. That's all I'm doing.



Also, I'm doing this on Django==1.11. This problem seems to go away on Django==2.0. I cannot easily upgrade to 2.0. Is there a workaround for this issue on 1.11?










share|improve this question
























  • what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
    – Satevg
    10 hours ago










  • Same results with werkzeug. Probably additional information needed on how your app being deployed.
    – Satevg
    9 hours ago










  • I added more info about my setup above.
    – Landon
    3 hours ago













up vote
2
down vote

favorite
2









up vote
2
down vote

favorite
2






2





I'm using DRF. I found that receiving a POST with more than 1024 characters causes a ~1 second penalty, while anything less than that is effectively free. I've simplified this into this trivial example:



# views.py
import time
from rest_framework.decorators import api_view
from django.http import HttpResponse

@api_view(['POST'])
def test_endpoint(request):

t = time.time()
data = request.body
total_time = time.time() - t

print('got post data:', round(total_time, 3))
return HttpResponse('body size:{} time:{}'.format(len(data), round(total_time, 3)))


# url.py
urlpatterns = [
url(r'^test_endpoint', test_endpoint),
]


You can see that all I'm doing is reading the request.body and measuring the time it takes to do so. Then I respond with that time, and the len of the request.body (to prove I accessed it).



Then I execute these curls:



$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 0123456782345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567901234567890123456789012345678901234567
body size:1024 time:0.0
real 0m0.045s
user 0m0.006s
sys 0m0.009s
$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 01234567823456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567890123456789012345678
body size:1025 time:0.999
real 0m1.020s
user 0m0.006s
sys 0m0.006s


You can see the second one has one extra character, and that causes a ~1 second penalty to ready request.body.



Why is that? How can I prevent this?



More Info



I made this as vanilla as I could. I created an new project with django-admin startproject helloworld_project .. I put the code above into it. And running it locally with python manage.py runserver. I don't have a webserver in front of it; I'm accessing it directly with my browser. That's all I'm doing.



Also, I'm doing this on Django==1.11. This problem seems to go away on Django==2.0. I cannot easily upgrade to 2.0. Is there a workaround for this issue on 1.11?










share|improve this question















I'm using DRF. I found that receiving a POST with more than 1024 characters causes a ~1 second penalty, while anything less than that is effectively free. I've simplified this into this trivial example:



# views.py
import time
from rest_framework.decorators import api_view
from django.http import HttpResponse

@api_view(['POST'])
def test_endpoint(request):

t = time.time()
data = request.body
total_time = time.time() - t

print('got post data:', round(total_time, 3))
return HttpResponse('body size:{} time:{}'.format(len(data), round(total_time, 3)))


# url.py
urlpatterns = [
url(r'^test_endpoint', test_endpoint),
]


You can see that all I'm doing is reading the request.body and measuring the time it takes to do so. Then I respond with that time, and the len of the request.body (to prove I accessed it).



Then I execute these curls:



$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 0123456782345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567901234567890123456789012345678901234567
body size:1024 time:0.0
real 0m0.045s
user 0m0.006s
sys 0m0.009s
$ time curl -X POST http://127.0.0.1:8000/test_endpoint -d 01234567823456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345679012345678901234567890123456789012345678
body size:1025 time:0.999
real 0m1.020s
user 0m0.006s
sys 0m0.006s


You can see the second one has one extra character, and that causes a ~1 second penalty to ready request.body.



Why is that? How can I prevent this?



More Info



I made this as vanilla as I could. I created an new project with django-admin startproject helloworld_project .. I put the code above into it. And running it locally with python manage.py runserver. I don't have a webserver in front of it; I'm accessing it directly with my browser. That's all I'm doing.



Also, I'm doing this on Django==1.11. This problem seems to go away on Django==2.0. I cannot easily upgrade to 2.0. Is there a workaround for this issue on 1.11?







python django django-rest-framework python-performance






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago

























asked 12 hours ago









Landon

2,71332136




2,71332136












  • what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
    – Satevg
    10 hours ago










  • Same results with werkzeug. Probably additional information needed on how your app being deployed.
    – Satevg
    9 hours ago










  • I added more info about my setup above.
    – Landon
    3 hours ago


















  • what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
    – Satevg
    10 hours ago










  • Same results with werkzeug. Probably additional information needed on how your app being deployed.
    – Satevg
    9 hours ago










  • I added more info about my setup above.
    – Landon
    3 hours ago
















what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
– Satevg
10 hours ago




what server do you use? nginx+uwsgi, werkzeug or ...? I cannot reproduce same problem with default runserver
– Satevg
10 hours ago












Same results with werkzeug. Probably additional information needed on how your app being deployed.
– Satevg
9 hours ago




Same results with werkzeug. Probably additional information needed on how your app being deployed.
– Satevg
9 hours ago












I added more info about my setup above.
– Landon
3 hours ago




I added more info about my setup above.
– Landon
3 hours ago

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53203078%2fdjango-rest-framework-post-slowness-when-body-size-greater-than-1024-character%23new-answer', 'question_page');
}
);

Post as a guest





































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53203078%2fdjango-rest-framework-post-slowness-when-body-size-greater-than-1024-character%23new-answer', 'question_page');
}
);

Post as a guest




















































































Popular posts from this blog

Schultheiß

Verwaltungsgliederung Dänemarks

Liste der Kulturdenkmale in Wilsdruff