Skip to content

[BUG] The engine isn't usable when running with a large number of databases. #1597

Description

@xbasel

Valkey supports up to INT_MAX databases. While most customers use the default (16 databases), if Valkey is started with a large number of databases, the engine's CPU usage increases significantly, rendering it almost unusable, even when the databases are empty and there is no incoming traffic.

For example, an engine which was started with

valkey-server --databases 10000000

exhibits a latency of over 200 milliseconds:

✗ time bin/valkey-cli ping
PONG
bin/valkey-cli ping  0.00s user 0.00s system 1% cpu 0.225 total

Perf shows:

# Children      Self  Command        Shared Object     Symbol
# ........  ........  .............  ................  .......................................
#
    97.78%     0.00%  valkey-server  valkey-server     [.] _start
            |
            ---_start
               __libc_start_main_impl (inlined)
               __libc_start_call_main
               main
               aeMain
               aeProcessEvents
               |
                --97.77%--processTimeEvents
                          serverCron
                          |
                           --97.73%--databasesCron
                                     |
                                     |--95.31%--activeExpireCycle
                                     |          |
                                     |           --76.50%--kvstoreSize
                                     |
                                      --2.42%--kvstoreSize

We can see the the CPU is busy (%70 utilization):

bin/valkey-cli info all |egrep "uptime|used_cpu_"
uptime_in_seconds:410
uptime_in_days:0
used_cpu_sys:1.842625
used_cpu_user:290.709860
used_cpu_sys_children:0.000000
used_cpu_user_children:0.000000
used_cpu_sys_main_thread:1.842629
used_cpu_user_main_thread:290.709501

Expected Behavior
The engine should remain responsive with low CPU usage when handling empty databases without any load.

Proposed Solutions

Lazy Initialization: Avoid allocating memory and data structures for databases that are never accessed. Initialize databases only when they are explicitly used.
Limit Maximum Databases: If the current architecture makes efficient handling of large numbers of databases infeasible, reduce the maximum number of databases supported or clearly document this limitation.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions