Should you operate an frp relay?
Choose frp if owning the public endpoint is part of your requirement. The documented setup puts frps and its configuration on a server with a public IP, and frpc beside the private service. That gives you control over the relay, while leaving its configuration and operation with you.
frp forwards TCP, UDP, HTTP and HTTPS traffic to services behind NAT or a firewall. The README at our tested commit includes SSH, domain-based web routing, DNS forwarding and private visitor examples. Those examples establish documented capabilities; our run did not validate those traffic paths.
What our sandbox actually established
Our run took place on August 23, 2026, at commit 758f07d59e155e1eb044d3ca6bb3151fdab737dc. The recorded sandbox image was golang:1.24-bookworm, with 3 CPUs and 8 GB of memory. The installation tail shows Go downloading go1.25.0, so the image name alone does not identify the toolchain used throughout the run.
The harness stores step status, exit code, elapsed time, parsed counts and a log tail. Installation was recorded as successful in 37 seconds. The build summary records success, exit 0 and 6 seconds, but its raw tail reports missing embedded dist assets and vet-exit:1. We preserve both observations because a successful wrapper status does not resolve the diagnostics inside it.
The test step returned exit 1 after 60 seconds and was not marked timed out. Its stored parser summaries report 33 passed, 6 failed and 39 total package results. Those figures do not establish exhaustive unique test coverage. Packages marked [no test files] are not failed or skipped tests.
Two failures are identifiable in the raw tail. The test/e2e suite reports load frpc-path error: stat ../../bin/frpc: no such file or directory. The test/e2e/compatibility suite reports load current-frps-path error: stat ../../bin/frps: no such file or directory. These messages explain why those suites could not proceed; they do not reconcile all six failures in the stored parser summary.
This record does not demonstrate a working public relay, successful E2E compatibility, reconnect behavior or production traffic handling. It contains no dependency audit result, so advisory findings and scan coverage are unknown. The MrKeyoor testing methodology explains how command outcomes reach the review. That page supplies provenance context, not proof that its current procedure governed this older run. No new execution was performed for this correction.
Public ports and private visitors solve different access needs
The documented SSH example exposes a local SSH service through a port on the public server. The HTTP example adds a virtual-host listener and DNS pointing at that server. Decide which service should be reachable before opening its relay port.
For access through another client, the README documents STCP with a preshared key. Its XTCP mode attempts direct data transmission between clients, but still needs an frps server and may not work with every NAT device. The README suggests falling back to STCP when XTCP does not work.
The tested-commit documentation also describes token and OIDC authentication between frpc and frps, TLS configuration and server port restrictions. Client authentication does not establish who may use the application you expose. Verify the application's own access controls as part of your deployment check.
Which alternative changes the decision?
cloudflared proxies traffic from the Cloudflare network to your origin. Consider it when you want Cloudflare in the traffic path rather than operating an frp public relay. This is a replacement architecture for that requirement, not an additional frp feature. Its README also describes client access for non-HTTP TCP traffic, so check the access model for your intended service.
rathole requires service tokens and splits each service's configuration between client and server. Consider it when that configuration model suits a tunnel through your own public server. Its README supports TCP and UDP service configurations and optional Noise or TLS transport. We did not compare its performance with frp.
bore forwards local TCP ports through a remote server. Consider it when TCP forwarding meets the requirement. Its optional secret authenticates the handshake; the README says further traffic is not encrypted by default. It is an alternative for that narrower task, not a replacement for frp's UDP or domain-routing capabilities.
What to verify before adoption
First produce the required binaries and web assets, then rerun the relevant E2E suites. In a staging network, check traffic through the chosen protocol, rejected credentials, exposed ports and recovery after a connection interruption. These are recommended acceptance checks, not results from our run.
Keep the tested commit separate from release identity. The attached v0.71.0 release page identifies release commit 4a23aa1; our run used 758f07d. The release notes describe a negative connection-pool denial-of-service fix and a mixed-case custom-domain validation fix. They do not turn our checkout into a verified release deployment.
How to read the retained scores
The retained ratings use a five-point editorial rubric: 1 means substantial documented obstacles, 2 means major gaps, 3 means a usable basis with material qualifications, 4 means strong documented support with an operational qualification, and 5 means extensive evidence for the specific dimension being rated. They are judgments, not benchmark results.
Setup ease rates the documented two-binary path, not a proven successful build in our sandbox. Documentation rates the breadth of concrete examples, not their independent execution. Community rates visible repository attention, not support quality or adoption. Maturity rates the documented feature set and maintenance evidence, not deployment reliability. The build conflict and incomplete E2E execution remain material limits regardless of these ratings.

