Skip to content

Add benchmark test and optimize byte slice reuse in network_reader#721

Merged
chombium merged 3 commits into
cloudfoundry:mainfrom
dlinsley:udp-ingress-gc-pressure
Jun 4, 2026
Merged

Add benchmark test and optimize byte slice reuse in network_reader#721
chombium merged 3 commits into
cloudfoundry:mainfrom
dlinsley:udp-ingress-gc-pressure

Conversation

@dlinsley

Copy link
Copy Markdown
Contributor

Problem

During performance testing of the gorouter with the udp-forwarder configured, we observed CPU consumption spikes in the udp-forwarder when the gorouter exceeds 1,500 requests per second. Profiling a benchmark revealed that the garbage collector consumes the majority of the CPU time because NetworkReader allocates a new byte slice for every single read.

Solution

This PR updates NetworkReader to use a sync.Pool for byte slice allocation, allowing the slices to be reused rather than constantly reallocated.

Impact

This change flattens memory usage and prevents the garbage collector from being overwhelmed when a large number of UDP messages are sent to the forwarder, resolving the CPU spikes under high load.

Benchmark comparison

benchstat old.bench new.bench
goos: linux
goarch: amd64
pkg: code.cloudfoundry.org/loggregator-agent-release/src/pkg/ingress/v1
cpu: 11th Gen Intel(R) Core(TM) i7-11850H @ 2.50GHz
                      │  old.bench  │              new.bench              │
                      │   sec/op    │    sec/op     vs base               │
NetworkReader_8KB-16    33.25µ ± 5%   24.27µ ± 11%  -26.98% (p=0.002 n=6)
NetworkReader_16KB-16   33.34µ ± 3%   22.15µ ± 22%  -33.55% (p=0.002 n=6)
NetworkReader_32KB-16   42.19µ ± 3%   23.77µ ±  9%  -43.66% (p=0.002 n=6)
NetworkReader_48KB-16   53.80µ ± 3%   28.38µ ±  5%  -47.26% (p=0.002 n=6)
NetworkReader_64KB-16   60.46µ ± 4%   30.75µ ± 21%  -49.13% (p=0.002 n=6)
geomean                 43.30µ        25.67µ        -40.70%

                      │  old.bench   │             new.bench             │
                      │     B/op     │    B/op     vs base               │
NetworkReader_8KB-16     8284.0 ± 0%   125.0 ± 3%  -98.49% (p=0.002 n=6)
NetworkReader_16KB-16   16476.0 ± 0%   125.5 ± 3%  -99.24% (p=0.002 n=6)
NetworkReader_32KB-16   32860.0 ± 0%   124.5 ± 4%  -99.62% (p=0.002 n=6)
NetworkReader_48KB-16   49245.0 ± 0%   122.0 ± 2%  -99.75% (p=0.002 n=6)
NetworkReader_64KB-16   65629.0 ± 0%   123.5 ± 4%  -99.81% (p=0.002 n=6)
geomean                 26.42Ki        124.1       -99.54%

                      │ old.bench  │             new.bench              │
                      │ allocs/op  │ allocs/op   vs base                │
NetworkReader_8KB-16    5.000 ± 0%   5.000 ± 0%       ~ (p=1.000 n=6) ¹
NetworkReader_16KB-16   5.000 ± 0%   5.000 ± 0%       ~ (p=1.000 n=6) ¹
NetworkReader_32KB-16   5.000 ± 0%   5.000 ± 0%       ~ (p=1.000 n=6) ¹
NetworkReader_48KB-16   5.000 ± 0%   5.000 ± 0%       ~ (p=1.000 n=6) ¹
NetworkReader_64KB-16   5.000 ± 0%   5.000 ± 0%       ~ (p=1.000 n=6) ¹
geomean                 5.000        5.000       +0.00%
¹ all samples are equal

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Testing performed?

  • Unit tests
  • Integration tests
  • Acceptance tests

Checklist:

  • This PR is being made against the main branch, or relevant version branch
  • I have made corresponding changes to the documentation
  • I have added testing for my changes

If you have any questions, or want to get attention for a PR or issue please reach out on the #logging-and-metrics channel in the cloudfoundry slack

@chombium

Copy link
Copy Markdown
Contributor

Thanks for the PR @dlinsley. The change looks pretty nice. I will fo few more test and then merge it.

@chombium chombium self-assigned this May 16, 2026
@dlinsley dlinsley force-pushed the udp-ingress-gc-pressure branch from cfcbab6 to 951434e Compare May 26, 2026 17:17
@dlinsley

dlinsley commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

@cloudfoundry/wg-app-runtime-platform-logging-and-metrics-approvers please let me know if there are any concerns or changes you would like to see here.

@chombium chombium left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi @dlinsley,

Thank you very much for your patience and for the fix. The performance improvements look impressive.
I have one small objection about the buffer size definition, apart from that LGTM :)

Comment thread src/pkg/ingress/v1/network_reader.go Outdated
Comment thread src/pkg/ingress/v1/network_reader.go Outdated
}

func BenchmarkNetworkReader_64KB(b *testing.B) {
benchmarkNetworkReaderWithSize(b, 65507) //65535 is the max UDP size, but we need to leave room for the headers: 20 for IPv4 and 8 for UDP

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great catch ;)

Comment thread src/pkg/ingress/v1/network_reader.go Outdated
@dlinsley dlinsley requested a review from chombium June 3, 2026 15:46

@chombium chombium left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the quick fix @dlinsley

LGTM!

@github-project-automation github-project-automation Bot moved this from Inbox to Pending Merge | Prioritized in Application Runtime Platform Working Group Jun 4, 2026
@chombium chombium merged commit 25da0f3 into cloudfoundry:main Jun 4, 2026
5 checks passed
@github-project-automation github-project-automation Bot moved this from Pending Merge | Prioritized to Done in Application Runtime Platform Working Group Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Development

Successfully merging this pull request may close these issues.

2 participants