Multipart forms by default?

30 views
Skip to first unread message

joost

unread,
Jun 14, 2010, 3:33:10 PM6/14/10
to Ruby on Rails: Core
Forms without explicit enctype are submitted as application/x-www-form-
urlencoded. This is the default behaviour in Rails. However, this
enctype does not allow transmission of binary data (files).

Would it not make sense to specify the enctype multipart/form-data by
default instead? i.e. all the form_for helpers would add this enctype
to the form tag, unless overriden by the developer.

This way, file uploads "just work" and normal key/value pairs continue
to work as well. There is no downside. I browsed through lighthouse
and only found obscure NN4 bugs related to multipart/form-data, which
I believe we can safely ignore. Even IE4 supports this enctype.

I can fork and make this change, but would like to float this idea
beforehand.

tschundeee

unread,
Jun 16, 2010, 4:45:57 PM6/16/10
to Ruby on Rails: Core
I like that idea. I don't see any downsides for that. Are there
performance differences when submitting an multipart form?

Joost Baaij

unread,
Jun 17, 2010, 3:29:36 AM6/17/10
to rubyonra...@googlegroups.com

Op 16 jun 2010, om 22:45 heeft tschundeee het volgende geschreven:

> I like that idea. I don't see any downsides for that. Are there
> performance differences when submitting an multipart form?

Yes there are: multipart forms send more data since every field has its own MIME header. From RFC2388:

"The multipart/form-data encoding has a high overhead and performance impact if there are many fields with short values. However, in practice, for the forms in use, for example, in HTML, the average overhead is not significant."

If this overhead was deemed not significant in August 1998, in my opinion it is even less significant now and this is a change we could make without any problems.

Joost.


>
> On Jun 14, 9:33 pm, joost <jo...@spacebabies.nl> wrote:
>> Forms without explicit enctype are submitted as application/x-www-form-
>> urlencoded. This is the default behaviour in Rails. However, this
>> enctype does not allow transmission of binary data (files).
>>
>> Would it not make sense to specify the enctype multipart/form-data by
>> default instead? i.e. all the form_for helpers would add this enctype
>> to the form tag, unless overriden by the developer.
>>
>> This way, file uploads "just work" and normal key/value pairs continue
>> to work as well. There is no downside. I browsed through lighthouse
>> and only found obscure NN4 bugs related to multipart/form-data, which
>> I believe we can safely ignore. Even IE4 supports this enctype.
>>
>> I can fork and make this change, but would like to float this idea
>> beforehand.
>

> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
>

Hongli Lai

unread,
Jun 17, 2010, 10:40:19 AM6/17/10
to Ruby on Rails: Core
On Jun 17, 9:29 am, Joost Baaij <jo...@spacebabies.nl> wrote:
> Yes there are: multipart forms send more data since every field has its own MIME header. From RFC2388:
>
> "The multipart/form-data encoding has a high overhead and performance impact if there are many fields with short values. However, in practice, for the forms in use, for example, in HTML, the average overhead is not significant."
>
> If this overhead was deemed not significant in August 1998, in my opinion it is even less significant now and this is a change we could make without any problems.

I don't think multipart parsing is very expensive nowadays, but I have
some doubts about the efficiency of the Rails/Rack multipart parser.
It performs a lot of string operations and if it creates a tempfile
even for small files then it can totally kill parsing performance.

Someone should benchmark this stuff.

Prem Sichanugrist

unread,
Jun 17, 2010, 10:43:24 AM6/17/10
to rubyonra...@googlegroups.com
+1 on benchmarking result. would love to see from

- Apache + Passenger
- Nginx + Passenger
- Mongrel
- Thin
- Webrick

What should be the method of benchmark?

Joost Baaij

unread,
Jun 17, 2010, 10:47:03 AM6/17/10
to rubyonra...@googlegroups.com
I can take a stab at this using AB, not until after next week due to a short vacation though.

Vanaf 18 juni ben ik een week op vakantie.
From June 18 I will be on vacation for a week.

joost

unread,
Jun 17, 2010, 2:46:05 PM6/17/10
to Ruby on Rails: Core
Here are some preliminary benchmarks, done with a fresh Rails 2.3.8
app, ruby 1.8.7, and a single render :nothing => true.

It does seem multipart forms are a bit slower overall, although they
were faster under webrick for a high number of parameters. As far as I
could tell the numbers scaled linearly.

In concrete terms, for Passenger, when posting 1000 simple parameters
the speed penalty is 0.764 ms (yes milliseconds).
Will repeat with a Rails 3 app too and post those results.
Benchmark script: http://gist.github.com/442546

Webrick:
= 1 key/value pair, 1000 posts
user system total real
default: 1.320000 0.150000 1.470000 ( 15.797317)
multipart: 1.400000 0.130000 1.530000 ( 16.273821)
= 1000 key/value pairs, 1000 posts
user system total real
default: 26.170000 0.570000 26.740000 ( 74.681545)
multipart: 26.130000 0.540000 26.670000 ( 74.073439)

Passenger
= 1 key/value pair, 1000 posts
user system total real
default: 1.250000 0.160000 1.410000 ( 25.887364)
multipart: 1.300000 0.150000 1.450000 ( 26.857967)
= 1000 key/value pairs, 1000 posts
user system total real
default: 26.060000 0.510000 26.570000 ( 70.453057)
multipart: 26.060000 0.480000 26.540000 ( 71.216598)

On 17 jun, 16:47, Joost Baaij <jo...@spacebabies.nl> wrote:
> I can take a stab at this using AB, not until after next week due to a short vacation though.
>
> Op 17 jun 2010, om 16:43 heeft Prem Sichanugrist het volgende geschreven:
>
>
>
>
>
> > +1 on benchmarking result. would love to see from
>
> > - Apache + Passenger
> > - Nginx + Passenger
> > - Mongrel
> > - Thin
> > - Webrick
>
> > What should be the method of benchmark?
>
> > On 17 มิ.ย. 2553, at 21:40, Hongli Lai wrote:
>
> >> On Jun 17, 9:29 am, Joost Baaij <jo...@spacebabies.nl> wrote:
> >>> Yes there are: multipart forms send more data since every field has its own MIME header. From RFC2388:
>
> >>> "The multipart/form-data encoding has a high overhead and performance impact if there are many fields with short values. However, in practice, for the forms in use, for example, in HTML, the average overhead is not significant."
>
> >>> If this overhead was deemed not significant in August 1998, in my opinion it is even less significant now and this is a change we could make without any problems.
>
> >> I don't think multipart parsing is very expensive nowadays, but I have
> >> some doubts about the efficiency of the Rails/Rack multipart parser.
> >> It performs a lot of string operations and if it creates a tempfile
> >> even for small files then it can totally kill parsing performance.
>
> >> Someone should benchmark this stuff.
>
> >> --
> >> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
> >> To post to this group, send email to rubyonra...@googlegroups.com.
> >> To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
> >> For more options, visit this group athttp://groups.google.com/group/rubyonrails-core?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group.
> > To post to this group, send email to rubyonra...@googlegroups.com.
> > To unsubscribe from this group, send email to rubyonrails-co...@googlegroups.com.
> > For more options, visit this group athttp://groups.google.com/group/rubyonrails-core?hl=en.

joost

unread,
Jun 18, 2010, 3:50:57 AM6/18/10
to Ruby on Rails: Core
Ran the benchmarks on Rails 3, which would actually suggest faster
multipart parsing for a small number of parameters. Otherwise the
numbers are similar. Hongli, thoughts?

= 1 key/value pair, 1000 posts
user system total real
default: 1.310000 0.240000 1.550000 ( 25.266783)
multipart: 1.360000 0.230000 1.590000 ( 23.380536)
= 1000 key/value pairs, 1000 posts
user system total real
default: 26.120000 0.730000 26.850000 ( 73.697901)
multipart: 26.330000 0.720000 27.050000 ( 74.567602)

Hongli Lai

unread,
Jun 18, 2010, 4:47:07 AM6/18/10
to Ruby on Rails: Core
On Jun 17, 4:43 pm, Prem Sichanugrist <sikand...@gmail.com> wrote:
> +1 on benchmarking result. would love to see from
>
> - Apache + Passenger
> - Nginx + Passenger
> - Mongrel
> - Thin
> - Webrick
>
> What should be the method of benchmark?

The web server has got nothing to do with it, it only forwards the
multipart data that the HTTP client sent. Don't benchmark the web
server, benchmark the multipart parser instead. Any difference that
you see is numbers is likely due to web server-specific things that
have got nothing to do with multipart parsing.

Hongli Lai

unread,
Jun 18, 2010, 4:50:44 AM6/18/10
to Ruby on Rails: Core
What I'd really like to see is a generic multipart parser written in C/
C++ that can be used in Ruby. mod_porter does the parsing for you in
the web server but unfortunately their parser depends on all kinds of
Apache stuff and can't be easily split off.
Reply all
Reply to author
Forward
0 new messages