feat(cli): add traffic limiting with configurable time periods#158
feat(cli): add traffic limiting with configurable time periods#158tmgrask merged 8 commits intoPsiphon-Inc:mainfrom
Conversation
|
Hi, we are actually in the middle of implementing a runtime schedule feature to achieve this. since #157 is a feature request we have discussed internally as well. This will enable all Conduit station operators (CLI and mobile) to set a runtime usage schedule, so that they can choose when their conduit gets used more or less. I will be preparing a PR soon |
|
Nice! these two features will work very nicely together. I'll be happy to adjust this PR once you merge your PR. |
|
Hi, we've been working on the idea of a built-in "reduced usage" window that can be used to tune usage limits down during some daily window. I was able to get the mobile side pretty close yesterday in #179 . This reduced usage window feature is probably more important for the mobile app where bandwidth and battery are more constrained. The goal is to enable users to run a highly active mobile conduit station overnight while their phone is plugged in and on WIFI, and a less active conduit station during the daytime when they need their battery and bandwidth to last. Still, I think it could be a useful thing for CLI operators running on bandwidth constrained hosts. Hooking this up to the CLI is just a matter of exposing the new I see this PR addresses bandwidth limits in a different way, by stopping the Psiphon controller when a certain bandwidth limit is hit. I am somewhat hesitant about this approach because this means disconnecting everyone connected to the station, which we would obviously like to minimize. Of course I can also understand that bandwidth is a limited resource in the cloud. I would feel better about this feature if we set large enough minimums so that we'd expect a conduit to remain active for some number of days before shutting down. Shutting down too frequently would also have a negative impact on Conduit reputation. If we had it setup so that you can't set --traffic-limit + --traffic-period to less than 500GB/month or something like that, I'd feel good about it! (Sorry about the many merge conflicts, I recently refactored the way the CLI parses the Notices that psiphon tunnel core emits.) |
Add automatic bandwidth throttling to manage data quotas without service interruption. When a configured traffic limit is approached, the system gracefully reduces capacity instead of shutting down, ensuring continuous availability and protecting proxy reputation. Features: - Configurable traffic limit (GB) and time period (days) - Automatic throttling at configurable threshold (60-90% of quota) - Graceful capacity reduction (reduced max clients and bandwidth) - Persistent state tracking across restarts via traffic_state.json - Automatic period reset and capacity restoration - Real-time traffic monitoring with controller restart support Configuration: - New flags: --traffic-limit, --traffic-period, --bandwidth-threshold, --min-connections, --min-bandwidth - Enforced minimums: 100GB minimum limit, 7 days minimum period - Default behavior: unlimited (no flags = no throttling overhead) Implementation: - Extended config.Options and config.Config with throttling parameters - Added validation for minimum values to protect reputation - Implemented trafficState persistence in service layer - Modified handleNotice() to track bandwidth usage - Enhanced Run() loop to support dynamic controller restart - Updated createPsiphonConfig() to use current (throttled/normal) values Benefits: - Never disconnects users - stays online 24/7 - No reputation damage from frequent shutdowns - Predictable bandwidth costs for cloud deployments - Existing connections drain gracefully during transitions Documentation: - Updated README.md with comprehensive throttling guide - Added docker-compose.yml example with recommended settings - Included configuration strategies (conservative/balanced/aggressive) Addresses maintainer feedback from PR discussion: implements throttling instead of hard stops to avoid user disconnections and reputation impact while still providing bandwidth management capabilities.
|
Hi, thanks for the feedback and the explanation. I've reworked the traffic limiting approach based on your feedback. Here's the new logic: Instead of stopping the service when hitting a traffic limit, it now throttles down gracefully:
This way no user disconnections and there is no reputation damage (stays online 24/7) while having the bandwidth management working. It also enforces minimums (100GB/7days) to prevent frequent restarts By default, if you don't set --traffic-limit, everything runs unlimited with zero overhead. Does this approach align better with what you had in mind? Happy to adjust the thresholds, minimums, or behavior based on your feedback. |
|
Hey, thanks for updating this. Unfortunately, restarting the controller like this does disconnect everyone who is connected. We don't have support for dynamically changing MaxClients right now. I think I am OK with the idea of stopping the process with the minimums you put in (100GB / 7 days w/ 60% min threshold = minimum of 60GB/week). However, I still feel uneasy about having this throttling machinery/behaviour around the main controller.Run invocation. Most CLI runners probably don't want to have any throttling. What do you think about implementing this "up a level"? Like some new script that manages the existing cli process when it sees the limits hit via the /metrics endpoint. The only downside with that idea is that /metrics then stops reporting anything during the "throttled" time period, but maybe that's OK since that is the desired state. |
|
I'm imagining something like: |
Implement traffic limiting via a new standalone `conduit-monitor` tool that manages the main service process, keeping the core codebase clean. Features: - New `scripts/monitor` supervisor that wraps the conduit process - Scrapes /metrics endpoint to track accurate bandwidth usage - Enforces limits by restarting child process with throttled settings (e.g., reduced max_clients/bandwidth) instead of hard shutdown - Persists traffic state across restarts via traffic_state.json - Enforces 100GB/7days minimums to protect proxy reputation Changes: - Reverted previous embedded throttling logic in service.go/config.go - Added `docker-compose.limited-bandwidth.yml` for easy deployment - Updated build system (Makefile/Dockerfile) to include monitor binary - Updated documentation with supervisor usage instructions This addresses maintainer feedback to move quota logic up a level and avoid complexity in the core service implementation.
|
Hey, Thanks for the feedback on the previous approach. I've reworked this to implement the supervisor pattern you suggested. Instead of adding throttling logic inside the controller, there's now a separate conduit-monitor tool in
The minimums are enforced: 100GB minimum quota, 7-day minimum period, threshold between 60-90%. This ensures at least 60GB/week before any throttling kicks in. There's a separate docker-compose.limited-bandwidth.yml so users with unlimited bandwidth can keep using the standard compose file unchanged. The main conduit codebase is untouched. One trade-off: as you noted, restarting does disconnect users. But with these minimums, restarts should be infrequent (at most once per week for heavy usage), and the throttled mode keeps the node running rather than going completely offline. However, I still believe having dynamically changing MaxClients support implemented in the upstream could make this 10x better as there would be no need to disconnect clients. Maybe that's something you guys can think about for next releases. |
tmgrask
left a comment
There was a problem hiding this comment.
Great, thanks for being flexible on this. This looks like a good solution for your use case for now.
dynamically changing MaxClients support implemented in the upstream could make this 10x better
Agreed, we like the idea of making this dynamically configurable. This is on our list, when it's ready I'll either make an issue about how it could be used on mobile and CLI or maybe just do it myself.
If you have time to fix those lint errors and to add the new binary to the release workflow, that would speed things up. I should be able to get to this in the next day or two if you don't.
Thanks for the contribution!
|
@AminAlam could you please sign the CLA as described in CONTRIBUTING.md, then I will merge and release. |
|
https://github.com/Psiphon-Inc/conduit/releases/tag/release-cli-1.5.0 The new binary is in the docker image |
Adds support for limiting total traffic usage over a specified time period, allowing Conduit node operators to manage bandwidth costs and stay within data caps.
Features
--traffic-limit,-t): Set total traffic limit in GB--traffic-period,-p): Set time period in daystraffic_state.jsonand persists across container restartsUsage
# Allow 500 GB of total traffic over 10 days: conduit start --psiphon-config ./psiphon_config.json --traffic-limit 500 --traffic-period 10This example allows 500 GB of total traffic over 10 days. When the limit is reached, the service waits for the period to end before resuming.
Updated
docker-compose.ymlto use local image with traffic limit flags and updated README.md with comprehensive documentation.How It Works
Service tracks total traffic (upload + download) during the configured period. When the limit is reached, the service pauses and waits for the period to end. After the period expires, traffic counters reset and service resumes automatically. Traffic state is persisted to disk for reliability across restarts