FAQ
Common questions about WhisperGraph: query performance, edge types, threat scoring, freshness, anonymous tier, and SDKs.
FAQ Documentation
Common questions about WhisperGraph and the documentation. If a question is missing, open a docs issue.
Why are some queries slow?
The two most common causes:
- Unanchored MATCH —
MATCH (h:HOSTNAME)scans 2.6 billion nodes. Anchor with{name: "..."}or another indexed property. - Fan-out without LIMIT —
(:HOSTNAME)-[:RESOLVES_TO]->(:IPV4)on a CDN hostname can return hundreds of rows per match. Default toLIMIT 20.
See Cypher Best Practices for the full do-this/not-that table.
What's the difference between physical and virtual edges?
Physical edges are backed by stored rows from observations (e.g. RESOLVES_TO from a DNS observation). They support edge-property filters: MATCH (a)-[r:RESOLVES_TO {firstSeen: "..."}]->(b).
Virtual edges are computed at query time from indexed properties. LISTED_IN, ANNOUNCED_BY, OPERATES are virtual. You can traverse them like any edge but you can't filter on edge properties (because there are none).
See Graph Schema and Glossary.
How is the threat score computed?
explain() returns a 0–10 score from a composite of:
- Feed count and weights — listed in 5 high-weight feeds scores higher than listed in 1 low-weight feed.
- Recency boost — recent listings get a multiplier; stale listings decay.
- Network density — IPs in dense malicious neighborhoods (other bad indicators in the same /24) score higher.
The exact formula and weights are evolving as feeds are added or rebalanced. Use the factors array in the explain() response to see how the score for a specific indicator was built. See Cypher Functions & Procedures for usage.
Can I write to the graph?
No. WhisperGraph is read-only via the public Cypher API. CREATE, MERGE, SET, and DELETE are not supported. The graph is populated by Whisper's ingestion pipeline (DNS, BGP, WHOIS, threat feeds) on a continuous basis.
If you need to keep your own enrichment alongside graph data, store it in your environment (Splunk KV Store, your SIEM, a side database) and JOIN at query time.
How fresh is the data?
| Data source | Refresh cadence |
|---|---|
| DNS observations (A, AAAA, CNAME, NS, MX) | Continuous, sub-minute on hot zones |
| BGP routing | Continuous, real-time updates from public collectors |
| WHOIS | Daily |
| Threat-intel feeds | Hourly incremental, daily full refresh — see Feed Catalog |
| RPKI status | Hourly |
| GeoIP | Weekly |
The whisper.history() procedure returns timestamped snapshots so you can see how data evolved over time.
What happens if my API key isn't being recognised?
If your key is missing, malformed, or revoked, requests run on the unauthenticated tier — they don't return 401. Symptoms: queries that worked previously now hit a depth limit, or rate limits look tighter than expected.
Fix: run CALL whisper.quota() to see which tier you're on, then check your key in the console. For tier limits see the pricing page.
What happens at quota?
You get a 429 with three response headers:
X-RateLimit-Limit— your per-minute quotaX-RateLimit-Remaining— queries left in this windowX-RateLimit-Reset— unix timestamp when the window resets
Wait until X-RateLimit-Reset and retry. For per-plan limits, see the pricing page.
Why isn't whisper.history() returning anything for my subdomain?
History is keyed on registrable domains. whisper.history("www.example.com") returns nothing; use whisper.history("example.com") and inspect subdomain history through the graph (MATCH (parent:DOMAIN {name: "example.com"})<-[:SUBDOMAIN_OF*1..3]-(sub:HOSTNAME)).
Are there language-specific SDKs?
Not yet — official Python and JavaScript SDKs are on the roadmap. In the meantime, see the Python and JavaScript examples in Getting Started. Community contributions welcome.
How do I report a bug or ask for help?
See How to ask for help.