refactor(destination): implement shared-filtering#15166
Open
refactor(destination): implement shared-filtering#15166
Conversation
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
alpeb
reviewed
Apr 17, 2026
Member
alpeb
left a comment
There was a problem hiding this comment.
Great changes, the Destination code definitely looks less entagled now 👍
Do you think it would be useful to expose metrics about the different filteredListenerGoups, or is that too much of an implementation detail?
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
Signed-off-by: Alex Leong <alex@buoyant.io>
alpeb
approved these changes
Apr 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In our testing and in reports from users, we have found that destination controller memory use scales linearly with the total number of concurrent subscribers that it servers. In one load test, we found the scaling rate to be approximately 330 kiB per subscriber. This causes the destination controller to use very large amounts of memory when there are a large number of subscribers. A cluster with 10,000 subscribers might expect the destination controller to use 3.4 GiB of memory.
Memory profiling revealed that the majority of this memory is consumed by the per-subscriber endpoint translator. More specifically, by the endpoint snapshot that it holds in order to calculate filtering and diffs to send to the client.
We reduce the memory scaling factor by noticing that this filtering and diff state can be shared between multiple subscribers if they have the same filtering conditions. In other words, subscribers only need their own state if they have different node-local or zone-local filtering. Therefore, we can group subscribers by a filter key where
all subscribers with the same filtering can share state.
To implement this, we break the unwieldy
endpoints_watcher.gointo a number of different files, aligned around the major types defined in this file:endpoints_watcher.go: the top level EndpointsWatcher typeservice_publisher.go: the servicePublisher type, per serviceport_publisher.go: the portPublisher type, per service portfiltered_listener_group.go: a newfilteredListenerGrouptype, per filter keyWe move the filtering and diffing logic out of
endpointTranlatorand intofilteredListenerGroupso that it can be shared. In this way,endpoindTranslatorbecomes a much simpler translation layer.With these changes, our load test measures up to an 84% reduction in destination controller memory use, depending on the distribution of subscriber filter keys.