IF you have coded a file upload component in .Net before you would have probably used the Asp.Net File Upload control. You would  have also come across the fact that the default HTTP Request size for a Web Application is set to 4MB. A search thereafter would have introduced you to the maxRequestLength Attribute that is configurable in your Web.config.

Increasing this value to say 40,960 will allow 10x the default file size to be posted to your web server. This will fix your immediate file size limitation to 40MB. But what it also means is that you have now opened your Web application to accept any request 10x the standard request length. The question you need to ask yourself is, is this a good thing or is this a bad thing.. ?

In this article I will explain how to go one step further and show how you can implement a buffered and streaming approach to file downloading and uploading…

Background Information

The quickest way to resolve file upload limitations in a ASP.Net Application is to increase the maxRequestLength attribute in the Web.Config.  Below is the snippet that is required to accomplish this:

<system.web>
  <httpRuntime maxRequestLength="40960"/>     <!-- 40MB limit, instead of 4MB limit -->
</system.web>

So is this good or bad.. ? In short, I believe this is a bad.

It’s a very quick solution, and if your application is relatively small to medium then this solution is quite possible and fairly robust. One important consideration is the side-effect this will have to your Web application. Instead of accepting a maximum web request size of 4mb, you have now allowed the server to be bombarded with up to 40mb of data per request.  You need to decide if this makes your server prone to attacks and security mishaps..

The solution I propose is to understand how packet sizes, buffering and streaming work. Once you understand how this works, I promise you will never go back! 🙂

Packet Sizes

The core concept behind streaming is the ability send many small packets of data as opposed to large packets of data across the wire.

Consider the following example:

  • You have a total network bandwidth of 100megabits/sec.  Which is equivalent to 12.5 MB/sec.
    Lets use 12MB for simplicity
  • You have 2 concurrent users.
  • Each user wants to transfer a 100MB file

The image below is a visual representation of our 12MB/sec network split into 3 sections.
Each section can handle 4MB.

4MB Example:

With maxRequestLength = 4MB, our 2 Users each use up 4MB out of the available 12MB bandwidth.
BLUE and GREEN successfully transfers 100MB each, totalilng 200MB in 25 secs.

note: Our network still has 4MB (RED) of bandwidth remaining for other traffic

40MB Example:

Now consider what happens if we increase maxRequestLength to 40MB.

  • BLUE has 100MB to transfer.
  • Each packet is 40MB because of our maxRequestLength value set to 40MB
  • A total of 2.5 packets need to be sent

BLUE uses up the entire 12MB bandwidth for a total of 100MB/12MB per sec = 8.33 secs.
So in 8.33 secs BLUE completes its data transfer.

  • GREEN also has 100MB to transfer.
  • Each packet is also 40MB
  • A total of 2.5 packets need to be sent

GREEN needs to wait for BLUE to finish before GREEN can begin its data transfer.
GREEN also takes 8.33 secs to transfer 100MB.

The entire process takes 16.6 secs to transfer a total of 200mb.

  • A 4MB environment takes 25 secs to send 200MB for 2 users.
  • A 40MB environment takes 16.6 secs to send 200MB for 2 users.

The latter would seem the better solution as it completes sooner. But your Network Infrastructure is crippled for a total of 16.6 secs as no bandwidth is available for other traffic across the network.

So hopefully this example has given you the information needed to understand why smaller packets are preferred over larger packets.