NewUnlimited creates a goroutine and a 1 ms ticker for each limiter. These keep running without requests, and every Take requires a channel exchange.
This cost multiplies in Subfinder, URLFinder, and TLDFinder, which create unlimited limiters per source. Local benchmarks measured approximately 1.47 seconds of CPU per wall-clock second for 1,000 idle limiters.
To reproduce, create multiple NewUnlimited(context.Background()) instances, issue no requests, and measure process CPU usage.
Unlimited mode should permit requests without a ticker, worker, or token exchange. The fix should preserve GetLimit, runtime setter behavior, and safe handling of Stop.
NewUnlimited creates a goroutine and a 1 ms ticker for each limiter. These keep running without requests, and every Take requires a channel exchange.
This cost multiplies in Subfinder, URLFinder, and TLDFinder, which create unlimited limiters per source. Local benchmarks measured approximately 1.47 seconds of CPU per wall-clock second for 1,000 idle limiters.
To reproduce, create multiple NewUnlimited(context.Background()) instances, issue no requests, and measure process CPU usage.
Unlimited mode should permit requests without a ticker, worker, or token exchange. The fix should preserve GetLimit, runtime setter behavior, and safe handling of Stop.