How to increase the default number of maximum server names and their length when using nginx

Learn how to increase the default number of maximum server names and their length when using nginx.

Increase server name length

You will hit the default server_names_hash_bucket_size limit when you define too long server name.

server_name very.very.long.domain.name.used.in.this.example.org;

This problem will be reported by nginx as an error and it will prevent it from starting.

$ sudo nginx -t
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: configuration file /etc/nginx/nginx.conf test failed

Default value is defined in src/http/ngx_http_core_module.c and corresponds to L2 cache line.

[...]
static char *
ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_core_main_conf_t *cmcf = conf;

[...]
    ngx_conf_init_uint_value(cmcf->server_names_hash_bucket_size,
                             ngx_cacheline_size);

    cmcf->server_names_hash_bucket_size =
            ngx_align(cmcf->server_names_hash_bucket_size, ngx_cacheline_size);
[...]

Function used to detect L2 cache line is defined in src/core/ngx_cpuinfo.c.

/* auto detect the L2 cache line size of modern and widespread CPUs */

void
ngx_cpuinfo(void)
{
    u_char    *vendor;
    uint32_t   vbuf[5], cpu[4], model;

    vbuf[0] = 0;
    vbuf[1] = 0;
    vbuf[2] = 0;
    vbuf[3] = 0;
    vbuf[4] = 0;

    ngx_cpuid(0, vbuf);

    vendor = (u_char *) &vbuf[1];

    if (vbuf[0] == 0) {
        return;
    }

    ngx_cpuid(1, cpu);

    if (ngx_strcmp(vendor, "GenuineIntel") == 0) {

        switch ((cpu[0] & 0xf00) >> 8) {

        /* Pentium */
        case 5:
            ngx_cacheline_size = 32;
            break;

        /* Pentium Pro, II, III */
        case 6:
            ngx_cacheline_size = 32;

            model = ((cpu[0] & 0xf0000) >> 8) | (cpu[0] & 0xf0);

            if (model >= 0xd0) {
                /* Intel Core, Core 2, Atom */
                ngx_cacheline_size = 64;
            }

            break;

        /*
         * Pentium 4, although its cache line size is 64 bytes,
         * it prefetches up to two cache lines during memory read
         */
        case 15:
            ngx_cacheline_size = 128;
            break;
        }

    } else if (ngx_strcmp(vendor, "AuthenticAMD") == 0) {
        ngx_cacheline_size = 64;
    }
}

Value of server_names_hash_bucket_size needs to be defined in http context, so you can use /etc/nginx/conf.d/ directory to alter default value.

$ echo "server_names_hash_bucket_size 128;" | sudo tee /etc/nginx/conf.d/server_names_hash_bucket_size.conf

Any custom value will be aligned (see src/core/ngx_config.h) to the L2 cache line value, for example value 129 will be aligned to 192.

#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1))

Increase number of defined server names

You will hit the default server_names_hash_max_size limit when you define too many server names using default server_names_bucket_size and server_names_hash_max_size values.

This problem will be reported by nginx as a warning and nginx will deal with it automatically (see src/core/ngx_hash.c file, ngx_hash_init function).

$ sudo nginx -t
nginx: [warn] could not build optimal server_names_hash, you should increase either server_names_hash_max_size: 512 or server_names_hash_bucket_size: 64; ignoring server_names_hash_bucket_size
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Default value is defined in src/http/ngx_http_core_module.c.

[...]
static char *
ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf)
{
    ngx_http_core_main_conf_t *cmcf = conf;

    ngx_conf_init_uint_value(cmcf->server_names_hash_max_size, 512);
[...]

Value of server_names_hash_max_size needs to be defined in http context, so you can use /etc/nginx/conf.d/ directory to alter default value.

$ echo "server_names_hash_max_size 1024;" | sudo tee /etc/nginx/conf.d/server_names_hash_max_size.conf

There is more to it, so I strongly suggest to read next section.

Additional information