Django REST Framework - POST slowness when body size greater than 1024 characters
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
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