lwIP was designed from the outset to have a low resource footprint. One of the techniques it uses to achieve this goal is its high level of configurability.
lwIP allows both coarse- and fine-grained control of functionality. Large sections of potentially unused functionality can be selected to be removed by the user, including entire protocol stacks. Such examples of removable coarse-grained functionality include UDP, TCP, SLIP, PPP stacks, ethernet/ARP support, IP fragmentation and/or reassembly, or the sequential API.
It has a somewhat modular and layered design to assist with this. It is intentionally only somewhat modular: other TCP/IP stacks have strictly enforced interfaces and abstractions between protocol layers. These abstractions are frequently cumbersome and can result in unnecessary resource implications. lwIP deliberately violates some of these protocol interface layering abstractions where doing so could improve resource utilization. An example is reserving an estimated appropriate amount of space for protocol headers when constructing packets, where the choice of protocol dictates the amount of space.
Where lwIP really stands out is in its fine-grained control over the various pools of resources. Most resources are compartmentalised into fixed size memory pools to allow sizes to be constrained deterministically. The application designer will know, or can choose, the maximum number of network connections which are to be supported depending on application requirements. They also know the level of data throughput required for transmission or reception and can control the levels of the necessary resources appropriately, such as numbers of buffers (separately for incoming or outgoing packet data) and their sizes, numbers of protocol control blocks, TCP window sizes and more.
In this way, application designers can choose a configuration that maximises performance within the limitations of available memory. Clearly, the more constrained the memory, the greater the potential for adverse consequences for performance, or the number of supported connections. However, it should be realised that even with copious quantities of memory resources available to lwIP, it cannot be expected that a stack intentionally designed from the outset to be sparing with memory will perform as well as a stack intentionally designed from the outset for high performance. Nevertheless careful tuning of lwIP almost always results in significant performance improvements.
A simple real-world test application, from a target platform with only a total of 128K of RAM, would when performing a simple test transmitting multiple 1400-byte packets obtain a throughput of > 1000k/s. However, the same platform configuration sending multiple 8192-byte packets would see the throughput drop to < 100k/s since fragmentation and buffer availability now impact the lwIP performance. System designers need to consider how the application makes use of the available lwIP APIs in conjunction with the resources available to maximise application network throughput.