Limits and Compatibility
This page collects the limits mentioned throughout the HTTPS decryption docs in one place.
Connections that can’t be decrypted
Section titled “Connections that can’t be decrypted”These are passed through (or, for pinned apps, fail to connect while decrypted):
| Case | Why |
|---|---|
| Apps with certificate pinning | They only accept their own certificate. Exclude hosts that diagnostics marks as pinned. |
| Apps that use only QUIC | MeowX blocks QUIC for listed hosts so apps fall back to TCP; apps that never fall back can’t connect. |
| TLS 1.2-only apps or servers | Only TLS 1.3 is decrypted. Hosts answered entirely locally are the exception on the server side. |
| App uses only HTTP/2, server only HTTP/1.1 | No conversion between versions. |
| Servers requiring a client certificate (mTLS) | MeowX doesn’t have the app’s client certificate. |
| Real ECH connections | The visible hostname is the outer one and doesn’t match the list. |
| Connections by IP address without a hostname | No certificate can be issued. Writing an IP in the list doesn’t help. |
| Selecting by app | iOS doesn’t reveal which app opened a connection (neither does MeowX on the Mac), so the list works by hostname only. |
| Mac: root services and tools such as curl, Python, Node | They don’t read the login keychain and don’t trust the certificate. Don’t list hosts they use. |
| Your provider’s dashboard and subscription domains, bypass list, APNs | Always direct, never decrypted. |
| Devices on your LAN using the local proxy | They don’t have your certificate. |
Surge module compatibility
Section titled “Surge module compatibility”| Feature | Status | Notes |
|---|---|---|
#!name, #!desc, #!author, #!icon, #!category, #!homepage |
Supported | |
#!system |
Supported | Module isn’t enabled on platforms it doesn’t list. |
#!requirement |
Partial | Recorded, not evaluated. |
#!arguments, {{{name}}} |
Supported | Undeclared references make the whole module unsupported (only the line in [Script] / [Body Rewrite]). |
{{{GATEWAY_ADDRESS}}} |
Not supported | |
[MITM] hostname, %APPEND%, %INSERT% |
Supported | Override syntax is treated as append. |
[MITM] hostname-disabled |
Supported | Can only disable positive entries. |
[MITM] skip-server-cert-verify |
Ignored | Security: only you can enable it in settings. |
[MITM] ca-p12, ca-passphrase, h2, others |
Ignored | HTTP/2 is automatic. |
<ip-address>, <ipv4-address>, <ipv6-address>, <simple-hostname> |
Partial | Accepted, no effect. |
[URL Rewrite] reject family, 302, 307 |
Supported | |
[URL Rewrite] header (transparent) |
Partial | Same host only. |
[Header Rewrite] |
Supported | Except Content-Length / Transfer-Encoding. |
[Map Local] text, tiny-gif, base64, file with https:// URL |
Supported | |
[Map Local] file with a relative or local path |
Not supported | |
[Body Rewrite] regex pairs, http-*-jq, jq-path |
Supported | |
[Script] http-request, http-response |
Supported | See Scripts. |
[Script] cron, event, generic, dns, rule … |
Not supported | |
[Rule] DOMAIN, DOMAIN-SUFFIX, DOMAIN-KEYWORD, IP-CIDR, IP-CIDR6, AND / OR / NOT |
Supported | Policies DIRECT, REJECT family, REJECT-DROP. |
[Rule] URL-REGEX with a reject policy |
Supported | Applied as a URL rewrite on decrypted hosts. |
[Rule] URL-REGEX with DIRECT/proxy, RULE-SET, DOMAIN-SET, USER-AGENT, PROCESS-NAME … |
Not supported | |
[General], [Proxy], [Host] and other sections |
Not supported | Each line counted as unsupported. |
Loon plugin compatibility
Section titled “Loon plugin compatibility”| Feature | Status | Notes |
|---|---|---|
Header lines, #!loon_version |
Supported | Version is recorded only. |
[Argument] (input, select, switch), {{{name}}}, ${name}, {name} |
Supported | |
[MitM] |
Supported | skip-server-cert-verify is ignored. |
[Rewrite] reject |
Supported | Drops the connection, as in Loon. |
[Rewrite] reject-200/img/tinygif/dict/array, 302, 307 |
Supported | |
[Rewrite] header |
Partial | Same host only. |
[Rewrite] header operations (request and response) |
Supported | Several headers per line. |
[Rewrite] mock-response-body |
Supported | data, data-path, mock-data-is-base64. |
[Rewrite] body replace-regex, json-jq, json-del/add/replace |
Supported | |
[Rewrite] reject-video, mock-request-body, other types |
Not supported | |
New syntax with ${url} ~= /…/ |
Partial | Reject family, header.*, body.replace, json.*, body.mock. |
New syntax with other conditions, or script(…), redirects and other actions |
Not supported | |
[Script] http-request, http-response |
Supported | |
[Script] cron and other types |
Not supported | |
[Rule] with PROXY |
Supported | Uses your main proxy group. |
HOST, HOST-SUFFIX, HOST-KEYWORD, IP6-CIDR aliases |
Supported |
Other formats, such as Quantumult X rewrite snippets and Stash overrides, aren’t supported as such: a file that isn’t recognized as a Loon plugin is read as a Surge module, and lines it doesn’t understand are listed as unsupported. Loon plugins whose [Rewrite] lines are written in Surge or Quantumult X order are recognized.
Platform limits
Section titled “Platform limits”| Limit | iOS | macOS |
|---|---|---|
| Simultaneous decrypted connections | 64 | 256 |
Buffered body per message (body rewrite, scripts with requires-body) |
512 KB | 10 MB |
| All bodies buffered at once | 4 MB | 64 MB |
| Body rewrites running at once | 1 | 4 |
| Scripts running at once | 1 | 2 |
| Stuck script threads tolerated | 1 | 4 |
| Script timeout | 10 s default, 60 s max | 10 s default, 60 s max |
| Regex time budget per body | 100 ms | 300 ms |
| jq steps / nesting depth | 3,000,000 / 256 | 20,000,000 / 512 |
| Map Local item | 512 KB | 2 MB |
| All Map Local data | 2 MB | 16 MB |
| Script or jq file | 2 MB | 8 MB |
| All scripts and jq files | 4 MB | 32 MB |
$persistentStore |
256 KB per value, 2 MB total | 256 KB per value, 2 MB total |
$utils.ungzip output |
8 MB | 64 MB |
| Literal-prefix rules across all modules (module not enabled beyond this) | 20,000 | 200,000 |
| Compiled regex memory before the “Too many rules” warning | about 2 MB | about 16 MB |
[Rule] routing rules from all modules |
10,000 rules / 512 KB | 10,000 rules / 512 KB |
| Module file size | 4 MB | 4 MB |
| Request records kept | 300 | 300 |
| Recorded memory, headers only | 1 MB | 1 MB |
| Recorded memory with bodies | 4 MB | 32 MB |
| Recorded body per direction | 64 KB | 256 KB |
| Recorded header size per record | 16 KB | 16 KB |
| Diagnostics entries | 500 | 500 |
| Per-host certificates cached in memory | 512 | 512 |
Timing
Section titled “Timing”| Item | Value |
|---|---|
| Wait for a complete TLS handshake | 500 ms (300 ms for the first byte on ports where a bare hostname matched, other than 443) |
| Certificate-pinning skip | 2 signals within 5 minutes → passed through for 1 hour |
| Server-failure skip | 10 minutes |
| Remote module update check | When returning to the app, at most every 24 hours; after a failure 1 hour, doubling up to 24 hours |
| Module and resource download timeout | 20 seconds |
| iOS profile download server | Stops after one download or 2 minutes |
| iOS downloaded profile | Deleted by iOS after 8 minutes if not installed |
