Skip to content

feat(server): implement LATENCY command set (Redis 7.0+ compatibility)#3461

Merged
git-hulk merged 3 commits into
apache:unstablefrom
gongna-au:feat-latency-commands
Apr 27, 2026
Merged

feat(server): implement LATENCY command set (Redis 7.0+ compatibility)#3461
git-hulk merged 3 commits into
apache:unstablefrom
gongna-au:feat-latency-commands

Conversation

@gongna-au

@gongna-au gongna-au commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR implements the LATENCY command for Kvrocks, focusing on the LATENCY HISTOGRAM subcommand introduced in Redis 7.0. It leverages the existing histogram infrastructure (histogram-bucket-boundaries config + CommandHistogram stats) to expose per-command latency distributions via the standard Redis protocol.

Changes

New File: src/commands/cmd_latency.cc

Implements CommandLatency with three subcommands:

  • LATENCY HISTOGRAM [command ...] — Returns a cumulative distribution of command latencies.

    • Output uses the Redis 7.0 format: outer map keyed by command name, each value is a map with calls (integer) and histogram_usec (map of boundary → cumulative count).
    • Frequency counts from CommandHistogram::buckets are converted to cumulative sums at output time.
    • Empty leading buckets are skipped (matching Redis behavior of omitting zero-count ranges).
    • The last bucket (overflow) is rendered as "inf".
    • Returns an empty map if histogram-bucket-boundaries is not configured.
  • LATENCY RESET [event ...] — Returns (integer) 0.

    • In Redis, this resets the spike-sampling event system (LATENCY LATEST/HISTORY/GRAPH), which Kvrocks does not have. Per Redis docs, histogram data is reset via CONFIG RESETSTAT, not LATENCY RESET. Returning 0 correctly indicates no event classes were reset.
  • LATENCY HELP — Returns usage information for all supported subcommands.

Build System

No changes needed. The file is automatically picked up by file(GLOB_RECURSE KVROCKS_SRCS src/*.cc) in root CMakeLists.txt.

Command Registration

Registered under CommandCategory::Server via REDIS_REGISTER_COMMANDS(Server, ...), same category as cmd_server.cc. This is safe because the macro generates unique static variables per translation unit using __LINE__.

Compatibility

Subcommand Redis Kvrocks Note
LATENCY HISTOGRAM [cmd ...] 7.0+ Yes Cumulative distribution, histogram_usec field, empty buckets skipped
LATENCY HELP 7.0+ Yes
LATENCY RESET [event ...] 2.8.13+ Yes Always returns 0 (no spike-sampling infrastructure)
LATENCY LATEST 2.8.13+ No Requires spike-sampling event system
LATENCY HISTORY event 2.8.13+ No Requires spike-sampling event system
LATENCY GRAPH event 2.8.13+ No Requires spike-sampling event system
LATENCY DOCTOR 2.8.13+ No Requires spike-sampling event system

Configuration Prerequisite

Histograms are only tracked when histogram-bucket-boundaries is set in kvrocks.conf. Example:

histogram-bucket-boundaries 1,5,10,25,50,100,250,500,1000,2500,5000,10000

If empty (default), LATENCY HISTOGRAM returns an empty map — this is expected behavior, not an error.

RESP Protocol Details

  • Uses RESP3 Map (%) via conn->HeaderOfMap(), which auto-degrades to interleaved RESP2 arrays.
  • Per-command entry structure:
    command_name => {
      "calls"          => (integer) N,
      "histogram_usec" => {
        boundary_1 => (integer) cumulative_count_1,
        boundary_2 => (integer) cumulative_count_2,
        ...
        "inf"      => (integer) total_calls
      }
    }
    

@git-hulk

Copy link
Copy Markdown
Member

@gongna-au Could you please add Go tests to ensure the new command works as expected?

@gongna-au gongna-au force-pushed the feat-latency-commands branch from b6c874c to 37d0dac Compare April 23, 2026 16:56
@gongna-au

Copy link
Copy Markdown
Contributor Author

@git-hulk already

@jihuayu jihuayu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Greate. Please skip commands with calls == 0 in LATENCY HISTOGRAM [command ...]. Redis returns an empty reply for commands with no recorded samples, rather than an empty histogram entry.

I have a small question: why did you put this command in a separate file instead of keeping it in cmd_server?

@gongna-au gongna-au force-pushed the feat-latency-commands branch from 37d0dac to 5f23f30 Compare April 24, 2026 01:59
@gongna-au

Copy link
Copy Markdown
Contributor Author

@jihuayu Good point! I've moved CommandLatency into cmd_server.cc alongside other server diagnostic commands (SLOWLOG, PERFLOG, etc.). Also fixed the calls==0 skip for filtered histogram queries. Thanks for the review!

Implement LATENCY HISTOGRAM, LATENCY RESET and LATENCY HELP subcommands
compatible with Redis 7.0 protocol. Skip commands with zero calls in
histogram output. Add Go integration tests covering all subcommands,
error handling, histogram output structure, filtering and zero-calls
exclusion.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@gongna-au gongna-au force-pushed the feat-latency-commands branch from 5f23f30 to 8353f68 Compare April 24, 2026 03:55
@git-hulk git-hulk enabled auto-merge (squash) April 27, 2026 12:42
@git-hulk git-hulk merged commit 855bad3 into apache:unstable Apr 27, 2026
71 of 73 checks passed
@sonarqubecloud

Copy link
Copy Markdown

nagisa-kunhah pushed a commit to nagisa-kunhah/kvrocks that referenced this pull request Apr 29, 2026
apache#3461)

## Summary
This PR implements the `LATENCY` command for Kvrocks, focusing on the
`LATENCY HISTOGRAM` subcommand introduced in Redis 7.0. It leverages the
existing histogram infrastructure (`histogram-bucket-boundaries` config
+ `CommandHistogram` stats) to expose per-command latency distributions
via the standard Redis protocol.

## Changes
### New File: `src/commands/cmd_latency.cc`

Implements `CommandLatency` with three subcommands:

- **`LATENCY HISTOGRAM [command ...]`** — Returns a cumulative
distribution of command latencies.
- Output uses the Redis 7.0 format: outer map keyed by command name,
each value is a map with `calls` (integer) and `histogram_usec` (map of
boundary → cumulative count).
- Frequency counts from `CommandHistogram::buckets` are converted to
cumulative sums at output time.
- Empty leading buckets are skipped (matching Redis behavior of omitting
zero-count ranges).
  - The last bucket (overflow) is rendered as `"inf"`.
- Returns an empty map if `histogram-bucket-boundaries` is not
configured.

- **`LATENCY RESET [event ...]`** — Returns `(integer) 0`.
- In Redis, this resets the spike-sampling event system (`LATENCY
LATEST`/`HISTORY`/`GRAPH`), which Kvrocks does not have. Per Redis docs,
histogram data is reset via `CONFIG RESETSTAT`, not `LATENCY RESET`.
Returning 0 correctly indicates no event classes were reset.

- **`LATENCY HELP`** — Returns usage information for all supported
subcommands.

### Build System
No changes needed. The file is automatically picked up by
`file(GLOB_RECURSE KVROCKS_SRCS src/*.cc)` in root `CMakeLists.txt`.

### Command Registration
Registered under `CommandCategory::Server` via
`REDIS_REGISTER_COMMANDS(Server, ...)`, same category as
`cmd_server.cc`. This is safe because the macro generates unique static
variables per translation unit using `__LINE__`.

## Compatibility

| Subcommand | Redis | Kvrocks | Note |
| --- | --- | --- | --- |
| `LATENCY HISTOGRAM [cmd ...]` | 7.0+ | **Yes** | Cumulative
distribution, `histogram_usec` field, empty buckets skipped |
| `LATENCY HELP` | 7.0+ | **Yes** | |
| `LATENCY RESET [event ...]` | 2.8.13+ | **Yes** | Always returns 0 (no
spike-sampling infrastructure) |
| `LATENCY LATEST` | 2.8.13+ | No | Requires spike-sampling event system
|
| `LATENCY HISTORY event` | 2.8.13+ | No | Requires spike-sampling event
system |
| `LATENCY GRAPH event` | 2.8.13+ | No | Requires spike-sampling event
system |
| `LATENCY DOCTOR` | 2.8.13+ | No | Requires spike-sampling event system
|

## Configuration Prerequisite
Histograms are only tracked when `histogram-bucket-boundaries` is set in
`kvrocks.conf`. Example:
```
histogram-bucket-boundaries 1,5,10,25,50,100,250,500,1000,2500,5000,10000
```
If empty (default), `LATENCY HISTOGRAM` returns an empty map — this is
expected behavior, not an error.

## RESP Protocol Details
- Uses RESP3 Map (`%`) via `conn->HeaderOfMap()`, which auto-degrades to
interleaved RESP2 arrays.
- Per-command entry structure:
  ```
  command_name => {
    "calls"          => (integer) N,
    "histogram_usec" => {
      boundary_1 => (integer) cumulative_count_1,
      boundary_2 => (integer) cumulative_count_2,
      ...
      "inf"      => (integer) total_calls
    }
  }
  ```

Co-authored-by: gongna-au <gongna1@xiaomi.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: 纪华裕 <jihuayu123@gmail.com>
nagisa-kunhah pushed a commit to nagisa-kunhah/kvrocks that referenced this pull request Apr 29, 2026
apache#3461)

## Summary
This PR implements the `LATENCY` command for Kvrocks, focusing on the
`LATENCY HISTOGRAM` subcommand introduced in Redis 7.0. It leverages the
existing histogram infrastructure (`histogram-bucket-boundaries` config
+ `CommandHistogram` stats) to expose per-command latency distributions
via the standard Redis protocol.

## Changes
### New File: `src/commands/cmd_latency.cc`

Implements `CommandLatency` with three subcommands:

- **`LATENCY HISTOGRAM [command ...]`** — Returns a cumulative
distribution of command latencies.
- Output uses the Redis 7.0 format: outer map keyed by command name,
each value is a map with `calls` (integer) and `histogram_usec` (map of
boundary → cumulative count).
- Frequency counts from `CommandHistogram::buckets` are converted to
cumulative sums at output time.
- Empty leading buckets are skipped (matching Redis behavior of omitting
zero-count ranges).
  - The last bucket (overflow) is rendered as `"inf"`.
- Returns an empty map if `histogram-bucket-boundaries` is not
configured.

- **`LATENCY RESET [event ...]`** — Returns `(integer) 0`.
- In Redis, this resets the spike-sampling event system (`LATENCY
LATEST`/`HISTORY`/`GRAPH`), which Kvrocks does not have. Per Redis docs,
histogram data is reset via `CONFIG RESETSTAT`, not `LATENCY RESET`.
Returning 0 correctly indicates no event classes were reset.

- **`LATENCY HELP`** — Returns usage information for all supported
subcommands.

### Build System
No changes needed. The file is automatically picked up by
`file(GLOB_RECURSE KVROCKS_SRCS src/*.cc)` in root `CMakeLists.txt`.

### Command Registration
Registered under `CommandCategory::Server` via
`REDIS_REGISTER_COMMANDS(Server, ...)`, same category as
`cmd_server.cc`. This is safe because the macro generates unique static
variables per translation unit using `__LINE__`.

## Compatibility

| Subcommand | Redis | Kvrocks | Note |
| --- | --- | --- | --- |
| `LATENCY HISTOGRAM [cmd ...]` | 7.0+ | **Yes** | Cumulative
distribution, `histogram_usec` field, empty buckets skipped |
| `LATENCY HELP` | 7.0+ | **Yes** | |
| `LATENCY RESET [event ...]` | 2.8.13+ | **Yes** | Always returns 0 (no
spike-sampling infrastructure) |
| `LATENCY LATEST` | 2.8.13+ | No | Requires spike-sampling event system
|
| `LATENCY HISTORY event` | 2.8.13+ | No | Requires spike-sampling event
system |
| `LATENCY GRAPH event` | 2.8.13+ | No | Requires spike-sampling event
system |
| `LATENCY DOCTOR` | 2.8.13+ | No | Requires spike-sampling event system
|

## Configuration Prerequisite
Histograms are only tracked when `histogram-bucket-boundaries` is set in
`kvrocks.conf`. Example:
```
histogram-bucket-boundaries 1,5,10,25,50,100,250,500,1000,2500,5000,10000
```
If empty (default), `LATENCY HISTOGRAM` returns an empty map — this is
expected behavior, not an error.

## RESP Protocol Details
- Uses RESP3 Map (`%`) via `conn->HeaderOfMap()`, which auto-degrades to
interleaved RESP2 arrays.
- Per-command entry structure:
  ```
  command_name => {
    "calls"          => (integer) N,
    "histogram_usec" => {
      boundary_1 => (integer) cumulative_count_1,
      boundary_2 => (integer) cumulative_count_2,
      ...
      "inf"      => (integer) total_calls
    }
  }
  ```

Co-authored-by: gongna-au <gongna1@xiaomi.com>
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Co-authored-by: 纪华裕 <jihuayu123@gmail.com>
@jihuayu

jihuayu commented Apr 29, 2026

Copy link
Copy Markdown
Member

Hi @gongna-au. Would you be willing to update the command list? https://kvrocks.apache.org/docs/supported-commands

@gongna-au

Copy link
Copy Markdown
Contributor Author

@jihuayu Sure, I can do that!💗

@gongna-au

gongna-au commented Apr 29, 2026

Copy link
Copy Markdown
Contributor Author

@jihuayu cc apache/kvrocks-website#371 done 💗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants