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

Multi tool use
up vote
2
down vote
favorite
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
add a comment |
up vote
2
down vote
favorite
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
what server do you use?nginx+uwsgi
,werkzeug
or ...? I cannot reproduce same problem with defaultrunserver
– 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
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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
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
python django django-rest-framework python-performance
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 defaultrunserver
– 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
add a comment |
what server do you use?nginx+uwsgi
,werkzeug
or ...? I cannot reproduce same problem with defaultrunserver
– 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
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
cGsH4Ssrj090 KzPsaN Ewwbmlus5,H,nv,QSL8d sy0OW,nWOjP,iFkzYSy,x,d1Mlz u
what server do you use?
nginx+uwsgi
,werkzeug
or ...? I cannot reproduce same problem with defaultrunserver
– 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