Tuning IKE_SA lookup

Since the 4.2.10 release the IKE_SA storage that was initially implemented using a linked list, can optionally be replaced with a more efficient hash table. However, linear search is just fine for clients and small gateways and is therefore still the default method. But if you are running a gateway with several thousand active IKE_SAs, you should consider optimizing the lookup by using the hash table approach.

Hash table size

Each entry in the hash table contains a linear list of IKE_SAs. In the default configuration, only one list is used and lookups are performed by searching the list.

The optimal size of the hash table depends on your setup and the number of IKE_SA you usually have installed on the box. A hash table entry for each IKE_SA is probably overkill, as each entry contains additional overhead. 5 to 20 IKE_SAs in each hash table entry is probably a good value. So if you expect to have 20000 clients connected simultaneously, you might choose a hash table size between 500 and 4000. If performance is really critical, you should do some tests to get the best value for your setup.

The hash table size is configured in strongswan.conf and should be a power of two, otherwise the table size will be rounded up to the next higher power of two:

charon {
    ikesa_table_size = 1024


In addition to the hash table size, you can define the number of locks to use for the hash table. If, for example, the hash table is divided in sixteen segments, an IKE_SA lookup will only lock one sixteenth of the table. This becomes important if strongSwan is running on multiple cores. The more segments you have, the more unlikely it gets that a core is blocked until the other has done the lookup.

You may choose the number of locks depending on the number of cores you have, but you could theoretically use a lock for each hash table entry. But keep in mind that additional locks will use additional resources. Using more than 512 segments has lead to instabilities on some systems!

The number of segments is at least one and at most the size of the hash table and should also be a power of two. In strongswan.conf, set:

charon {
    ikesa_table_segments = 16

Implementation details

The lookup using the hash table is optimized for IKE responders, as an initiator does usually not set up several thousand tunnels. Initiators search for existing IKE_SAs to check if there is one to reuse. As this lookup is not optimized you'll benefit only from less locking conflicts due to more segments. To disable the reuse of IKE_SAs (and skip that search), set:

charon {
    reuse_ikesa = no

This should speed up the lookup for IKE_SA initiation.

For more information and implementation details, have a look at the IKE_SA Manager implementation (source:src/libcharon/sa/ike_sa_manager.c).