FAQ

Frequently Asked Questions


Free 60-Day Trial

Sign up free and get the full platform for 60 days — no credit card required. Or skip the signup and explore a live sandbox organization with real data in seconds.

START 60-DAY TRIAL TRY A SANDBOX


What is Temporal Intelligence?
What is GroveStreams?
Who would use GroveStreams?
What is meant by high performance and near real-time?
Do I need to buy or lease servers?
How am I billed?
Is GroveStreams secure?
How does data get into GroveStreams?
Can I control remote systems using GroveStreams?
What are TW, TDQ, and TEQ?
What are Components and Streams?
What's a Derived Stream?
What are FK-Resolved Dependencies?
What's a Component Template?
What is a GroveStreams Organization?
How often can a Feed be uploaded?
Do you support automatic deleting of data?
What are Cycles and Rollup Calendars?
Do you have Time Zone support?
Do you support monitoring and tracking mobile geo locations?
How are Time Filters used?
What is the AI Assistant and what can it do?
Can I manage my schema through GS SQL?
What is MCP and how do I use it with GroveStreams?
How is MCP different from the ODBC/JDBC adapter?
Can my organization disable MCP?
How much functionality is exposed in the GroveStreams' RESTful API?
Does GroveStreams Support Custom Branding?


Answers

What is Temporal Intelligence?

Temporal intelligence is the ability to store, query, and reason across the complete history of every value and every relationship in your data — not just the current state. It means every data point knows when it happened, every relationship knows when it changed, and every query can travel through time.

Traditional databases store the current state and discard what came before. A temporal intelligence platform preserves the full history natively — every cell in the relational model holds up to 100 million timestamped values, not just one — so any query can reach any point in time, and AI agents, analysts, and automated systems can reason over years of context without pre-aggregation. One primitive — the stream — replaces the history tables, triggers, materialized views, batch roll-up jobs, and junction tables that most approaches require you to build from scratch.

What is GroveStreams?

GroveStreams is the temporal intelligence platform with built-in analytics, forecasting, and an AI query layer. It provides real-time decision making capabilities to organizations across industries as data arrives from many sources.

GroveStreams Cloud

GroveStreams is designed so that your business or organization can quickly react to changes as they're happening. GroveStreams isn't just built to allow you to react to data — it's also built to allow your systems and AI agents to react accordingly by using the GroveStreams platform independent open API.

The volume and variety of data that organizations generate increases every day. Traditional systems cannot effectively capture, analyze and react to the amount of data being generated in a timely manner. GroveStreams has been built from the ground up on a purpose-built temporal storage engine designed for massive scale. It brings enterprise-grade scalability and reliability to your business or organization.

GroveStreams stores all data and tracks changes over time. It is an open platform, in the cloud, that any organization, user, or system can take advantage of.

 

GroveStreams specializes in:

GroveStreams Dashboard



Who would use GroveStreams?

Anyone or any system that needs to collect large amounts of data, track changes over time, analyze it, and react to it quickly. Whether you want to monitor one data stream from a single source or many more streams from many sources, GroveStreams is available to you and others including:

Use GroveStreams when you:



What is meant by high performance and near real-time?

GroveStreams can run on hundreds of servers that utilize partitioning and parallel processing. Most transactions happen within milliseconds including uploading and downloading tens of thousands of metrics. For example, a GroveStreams request to download one day of second samples (86,400 values) usually takes under 1 second.

The GroveStreams API supports the batching of samples across streams and components during uploading or downloading. This can allow for many streams and their samples to be uploaded with sub-second response times.

Long running tasks are managed by the GroveStreams job framework. An example of a long running task is a component reconcile job. If a user changes a stream's interval size or its data type and the stream has several years of one second data, it could take some time updating all this data, so a job is kicked off and runs asynchronously. Feeds can still be uploaded/downloaded while jobs are running. Note that some jobs, such as the reconcile job, require that a feed only append data while a job is running.

Component locations, roll-up calculations, gap filling, constraints, event detection and notifications occur as feeds are uploaded.>



Do I need to buy or lease servers?

No. Data from one or more sources can be uploaded directly into GroveStreams as long as the source has Internet access. The option to lease an entire private cluster is available to large customers.



How am I billed?

GroveStreams is free for small users. Larger users will be billed monthly via a registered credit card. Enterprise customers may request monthly invoicing.

User limits and other plan caps (components, samples, organizations) vary by tier — from a few users on the free trial to unlimited on Enterprise and Strategic plans. Visit our pricing page and the pricing FAQ page for current limits and details.



Is GroveStreams secure?

Yes. Our data center is SOC2 certified. The GroveStreams website is password protected and allows for all requests to occur via SSL. Strong passwords, that expire, can be configured along with two factor authentication (2FA).

Security is enforced at the query layer. When users interact through the UI, GS SQL, the AI assistant, ODBC/JDBC connections, or OAuth-authenticated OData connections, role-based access control is enforced inside the query engine itself. If a user doesn't have read access to a component, that component's data is absent from query results entirely — not just hidden in the UI.

Dashboards are security-aware. The same dashboard viewed by two different users will show different sets of components based on each user's access rights. An operations manager sees their region's data; a field technician sees only their assigned equipment — same dashboard, same URL, different data.

API keys provide a separate security model for system-to-system integration, scoped by endpoint, resource type, IP address, and domain whitelist.

Our HTTP API uses access keys.
Our MQTT API uses X.509 certificates.

Both APIs can have specific rights assigned for resource types and/or specific resource instances. See the Developers page for more details about API keys.



How does data get into GroveStreams?

Data is uploaded into GroveStreams via the Temporal Wire (TW) ingestion layer in several ways:

MQTT API Monitoring and testing can be done within Observation Studio:
GroveStreams - MQTT Monitoring



Can I control remote systems using GroveStreams?

Yes. The easiest and most secure method is with our MQTT servers and X.509 certificates.

A secondary HTTP technique is to return a command or configuration signal back to the system every time it sends data to the platform. This technique allows commands to travel through a firewall without having to configure your firewall.



What are TW, TDQ™, and TEQ™?

GroveStreams exposes three API layers, each addressing a different stage of the data lifecycle:

TDQ and TEQ share the same grammar, functions, and operators — they differ only in how tables and columns are resolved. Together with TW, they form a complete pipeline: ingest with TW, query internals with TDQ, query your semantic model with TEQ.



What are Components and Streams?

A Stream represents a collection of one or more data points. Each data point can be associated with a single time stamp or a time range. Timestamps are accurate to the millisecond.

There are three types of streams:

Stream data types can be numbers, dates and times, text, booleans (yes,no), longitude, latitude or elevation. Each Stream can have time filters, constraints, gap filling methods, a unit and other items applied to its feed data as it is uploaded. Stream data can be uploaded via the GroveStreams' API or a stream can be defined as a derived stream. It is not required for a component to upload all of its streams at the same time with the exception of mobile components. Mobile components are required to upload their longitude and latitude streams at the same time.

A component is a "thing" that is also a container for a group of streams and events that share a similar context. For example, a component might be an energy meter that monitors voltage and power. Voltage would be one stream and power would be another stream. If the component were mobile, it could also have latitude and longitude streams that record its location over time.

A component is an abstract concept that represents physical "things" or non-physical "things". Examples of components:



What's a Derived Stream?

Streams can be configured to be derived from RSS feeds or from expressions.

From RSS Feed: Streams can be derived from internal or external RSS feeds. GroveStreams allows for a simple filter to be applied to RSS feed results so that certain values can be extracted from a feed.

RSS feeds are a popular way of bringing external data into GroveStreams for mashing up with other streams. Many RSS feeds are available on the Internet including:

Weather data Stock quotes Currency Exchange Rates External, 3rd party data feeds

GroveStreams updates RSS derived streams hourly.

From Aggregation:
Streams can be derived from aggregating two or thousands other streams. Calculate statistics such as the maximums, minimums, sums, averages and gap counts for each interval in the aggregation time range. Aggregation is started manually or it can be scheduled to run periodically since it can be a lengthy process.

From Expression:
A derived expression stream is calculated from any other component streams within an organization. Calculations can occur as data arrives from API calls or periodically (every one to three minutes) for large batch calculations. Derivation only happens when dependents have data available for the time period being calculated. The engine automatically handles time alignment, windowing, and rollups — different stream cycle sizes and interval offsets can be used inside a derivation expression without any manual window management.

Derived streams are just like other streams except that their feed data is derived by the GroveStreams derivation engine. They can be graphed, monitored in dashboards, and used as dependents in other derived streams, creating computation graphs of any depth.

FK-Resolved Dependencies (Cross-Entity Derivation):
Expression variables can optionally include a Resolution SQL statement that dynamically resolves which stream to use at derivation time. This enables temporal relationship resolution — when the relationship between entities changes over time, the derivation engine automatically detects the change points, splits the derivation range into segments (one per stable relationship period), and derives each segment using the correct target entity's data.

For example, an energy meter connected to Customer_A from January through June, then moved to Customer_B in July, will derive the first half of the year using Customer_A's rate data and the second half using Customer_B's rate data — automatically. Multi-hop chains are supported (e.g., meter → customer → supplier), with the engine walking each hop and detecting relationship changes at every level.

We're not aware of another platform that does this declaratively. On the platforms we've evaluated — time-series databases, stream processors, cloud data warehouses, and traditional RDBMS setups — handling relationship changes during a calculation requires custom pipeline code to detect change points, split time ranges, re-resolve targets, and stitch results. In GroveStreams, it's a single SQL expression on the variable definition. See our Derived Streams guide for full details and comparisons.

Expression variables are streams. If a variable is an interval stream, then the user can choose the interval offset for that variable. For example, if an hourly interval with a time span of 2:00 pm to 3:00 pm is being calculated, a dependent variable's offset can be set to -1 and that variable's data for time span 1:00 pm to 2:00 pm will be used in the calculation. Offsets are useful for things like calculating rolling averages or comparing monthly costs.

Expressions can contain any stream data types, conditional "if" operators (<=,>=, <,>, !=, ==, &&, ||) and many functions (trig, log, exponents, absolute value, statistical, string, JSON, time formatting, and more).

Example of a derived stream expression that calculates one second 3 point rolling averages from component1.stream1:

Variables:

Variable Offset Stream Cycle Cycle Function
n 0 component1.stream1 Second -
n_minus_1 -1 component1.stream1 Second -
n_minus_2 -2 component1.stream1 Second -

Expression:
(n + n_minus_1 + n_minus_2) / 3

Example of a derived stream expression with an FK-resolved dependency that calculates energy cost using the current customer's rate — automatically following customer reassignments over time:

Variables:

Variable Stream Resolution SQL Cycle Function
kwh meter1.energy - Hour SUM
rate - SELECT customerUid, 'rate' FROM meter WHERE cuid = @cuid - -

Expression:
kwh * rate

If the meter was connected to Customer_A (rate = $0.12/kWh) from January through June, then reassigned to Customer_B (rate = $0.15/kWh) in July, the derivation engine automatically uses $0.12 for Jan–Jun and $0.15 for Jul–Dec. No custom code required.

Other usages of Derived Streams:

Derived stream variables can be different data types. A stream defined as text can be derived from the sum of two other streams of types long and double. GroveStreams will attempt to do the data type conversion wherever it is possible. If the conversion is not possible, the resulting interval will be considered a Gap or NULL.

For full details on derived streams — including temporal relationship resolution, comparison with other platforms, derivation triggers, and performance characteristics — see the Derived Streams guide.



What are FK-Resolved Dependencies?

FK-resolved dependencies enable temporal relationship resolution inside the derivation engine — a capability we're not aware of any other platform offering declaratively. In the real world, relationships between entities change over time — meters move between customers, sensors are reassigned between production lines, instruments transfer between trading desks. When you derive a stream that depends on a related entity's data, you need the correct related entity for each point in time.

With FK-resolved dependencies, instead of pointing a variable directly at a fixed stream, you provide a Resolution SQL statement. The derivation engine parses this SQL, follows the foreign key chain through your data model, loads the FK stream history to detect when relationships changed, and automatically splits the derivation into segments — one per stable relationship period. Each segment is derived with the correct target entity's data, and the results are stitched together automatically.

For example, if a meter's customerUid stream shows it was connected to Customer_A from January through June, then Customer_B from July onward, a cost derivation (kwh * rate) automatically uses Customer_A's rate for Jan–Jun and Customer_B's rate for Jul–Dec. Multi-hop chains are supported (e.g., meter → customer → supplier), with the engine detecting relationship changes at every level and producing the correct segments.

We're not aware of another platform that does this natively. On the platforms we've evaluated — time-series databases, stream processors, cloud data warehouses, and traditional RDBMS setups — handling relationship changes during a calculation requires custom pipeline code to detect change points, split time ranges, re-resolve targets, and stitch results. In GroveStreams, it's a single SQL expression on the variable definition. See the FK-Resolved Dependencies section of the Derived Streams guide for full details.



What's a Component Template?

Large organizations typically have a large number of entities that are identical (such as utility electric meters). It makes no sense to manually create a new component instance by hand every time a new entity comes on-line.

A component template is used to simplify creating multiple component instances that only differ by a few attributes and stream feed data. When a component uses the feed API to upload data it can pass in a component template Id. A component instance will be created automatically within the organization, if a component does not already exist for that feed (also known as automatic registration).

One or more components created from a component template can remain linked to that template. Any changes made to a template can be applied to all components linked to it. This makes mass modeling changes easy to do without any required programming.

Live schema evolution: When you modify a template — add a stream, remove a stream, change a data type — GroveStreams automatically reconciles every linked component. This runs in the background with zero downtime: queries continue to return results and data continues flowing into streams throughout the process. Internally, changes are reconciled into a temporary stream. Once complete, the component is briefly locked, any new data that arrived during reconciliation is merged, and the temporary stream replaces the original. This means tens of thousands of components can be updated from a single template change while the platform stays fully operational.



What is a GroveStreams Organization?

An organization is a Workspace, typically representing a home, business, or organization. Each organization has its own set of components, streams, dashboards, maps, and other items. An organization allows you to control user and API access to the organization. You are automatically the "owner" and given full access rights when you create an organization. Other users may invite you to their organizations with rights they give you. All of the organizations, you "own" or are a member of, will appear in your GroveStreams start page (the first page that appears when you sign in).

GroveStreams data is store hierarchically in this manner:

Organizations
        Components
                Streams
        Component Templates
        Maps
        Dashboards



How often can a Feed be uploaded?

Multiple streams can be uploaded in batch from each public facing IP source every ten seconds or longer. Note that the stream may sample every second and upload those 10 samples every 10 seconds. See the HTTP API Limits and MQTT Limits pages for more details.



Do you support automatic deleting of data?

Yes. Some users may wish to retain stream data for a short period of time. A "delete profile" can be created and associated with each stream. Each profile specifies a user defined time span to retain stream data. A couple of times a day, the GroveStreams delete profile system job will run and delete stream data according to its delete profile. GroveStreams is not a round-robin database (RRD). Data is retained as long as you need it.



What are Cycles and Rollup Calendars?

Cycle
Each interval stream's data time range is specified by the base cycle associated with a stream. A cycle is a user defined recurring period. A cycle can be defined to be fixed or custom:

Examples of Fixed Cycles:

Example of Custom Cycle:

The time zone is used for the start datetime for fixed cycles and for the start and end datetimes for custom cycles. The time zone can be set to use the component's time zone so that the same cycle can be used across time zones.

Rollup Calendar
A rollup calendar defines how stream data can be rolled-up for viewing and analysis. Rollup calendars are optional.

If a stream has a base cycle set for one second intervals, it quickly becomes cumbersome to view and analyze a year of data which is 31,536,000 intervals. For the "float" data type which is 4 bytes, a years worth of data would be about 120 Megabytes. Instead of downloading 31 million intervals and sifting through them, a user is better off downloading a set of rolled-up stream data at a larger interval size and then drilling in on the interesting cycles. A good example of a graph that demonstrates the power of roll-ups is the Google finance Graph. Unfortunately, unlike GroveStreams, Google hard-coded their roll-up cycles (1d, 5d, 1m, 6m, 1y, 5y).

Also, you may want to monitor your energy usage in 1 second intervals so as to watch for certain events, but you are probably billed based on monthly kW and or kWh. A stream with a rollup calendar would be an ideal solution. You can view/monitor 1 second intervals and you can also view/monitor your one hour and one month cycle intervals too, at the same time. You'll be able to watch your one month cycle interval change nearly every second... actually, every 10 seconds since you can only upload every 10 seconds :(

A rollup calendar is defined by simply referencing a collection of cycles, described above. When the rollup calendar is saved, it will be sorted and validated that it contains no gaps. A stream's feed can only be uploaded to the base cycle. Any stream non-base cycle information can be used (graphing and such) just like the base cycle.

Example
Let's define a rollup calendar that rolls one second data into several other cycles up to a year: Cycles that were defined earlier and that the rollup calendar will reference:

After the rollup calendar is defined and associated with a stream, the stream's data for each rolled-up cycle is available as base cycle data is uploaded. When the stream uploads 10 intervals of data (1 second each), all the rollup data is immediately available via the API and browser user interface. Rollup cycle data can be requested with these functions:

Gap intervals are ignored for some of the above functions (First, Last, Min, Max, Avg, Min Occurrence, Max Occurrence) for interval streams.

Only base cycle information can be uploaded via interval stream feeds. The other feeds are calculated and therefore cannot be uploaded. Rollup feeds reflect any changes to base cycle data during any time period.

Note that an interval stream's base Cycle does not have to exist within the rollup calendar it is referencing. It just needs to be able to "fit" evenly into one of the cycles and it will be rolled-up from the one that it fits into and above. For the example above, a stream might have a base cycle of "30 Minute". It would upload a value for each 30 minute interval and that value would start rolling up to 1 Hour then to 1 Day and so on up to a Year.

What does "fit" evenly mean? A cycle defined as "7 Seconds" will not fit evenly into a rollup cycle defined as "8 Seconds" or "1 Minute" but will fit evenly into a cycle defined as "42 Seconds".



Do you have Time Zone support?

Yes. Our time zone support is very flexible. All components must reference a Time Zone. All cycles reference a time zone or point to a component's time zone.

Rollup calculations use the time zone and cycle reference date to determine the actual UTC time to associate with the rollup interval times. When data is requested via the API it is always requested using UTC datetime epoch milliseconds.

The ability to fix a time zone to a cycle or to a component allows for rollups to occur in a specific time zone (such as the corporate headquarters). For example, an oil company may want to monitor daily oil production from each well. Their definition of a day might be the corporate headquarters time zone day. They would set their time zone in each rollup cycle, forcing each well's daily oil production to be calculated using the corporate headquarters definition of a day. If the same oil company wanted to track production in each well's time zone then they would just point each rollup cycle time zone to the component's time zone.



Do you support monitoring and tracking mobile geo locations?

Yes. A component can have fixed geo coordinate attributes or a component can have a stream for each geo coordinate so yes, GroveStreams allows for storing, retrieving, deriving and rolling-up (basically you can do anything to/with a longitude or latitude stream that you can do with other streams). Geo coordinates are stored as double value types. Geo streams can be regular, interval, or point streams.

A component's current location, along with any of its active events, can be viewed in a map.



How are Time Filters used?

Time Filters allow for the ignoring of samples that occur during specified time spans (seasons) and time intervals for each day of the week.

Time Filters are useful for things such as extracting energy time-of-use billing determinates or detecting if a door was opened on a certain day and at a certain time.

Time filters are applied to stream feeds as they are uploaded or derived. Sample times or interval ranges not included in the filter are converted to Gaps (or null values) for interval streams and ignored for regular streams. This is advantageous because:



What is the AI Assistant and what can it do?

The GroveStreams AI Assistant is an agentic system with access to over 35 built-in tools. You pick from a curated set of LLM profiles spanning OpenAI, Anthropic, Gemini, and xAI — your organization admin controls which profiles are available to your users and which one serves as the org default — and the assistant autonomously reasons about your requests, executes tools, and returns final answers. It is available within the GroveStreams web application and as an HTTP API for integration with external applications and AI agents.

Key capabilities:

The assistant retains context across a conversation, so you can ask follow-up questions without repeating yourself. All tool calls run under your user security context — the assistant can only access and query objects you have permissions for.

Brain and Minion tiers. Each LLM profile pairs two models: a Brain for the main reasoning loop and a Minion for lightweight delegated work like documentation search and query rewriting. The Minion is typically a cheaper, faster model paired with a more capable Brain (e.g., GPT‑5‑nano with GPT‑5, or Claude Haiku with Claude Sonnet) so main-loop quality stays high while routine sub-agent work stays inexpensive. Brain and Minion bill at their own per-token multipliers. See the AI Assistant page for which sub-agents run at which tier.

Per-model multipliers track third-party LLM provider pricing in good faith but may lag behind vendor price changes — sometimes by hours, sometimes by weeks. Multipliers may be revised at any time without notice and revisions are not retroactive. AI Assistant credit charges are final once metered and are not refundable based on multiplier lag. See Terms of Service Section 10.8 for the full disclosure.

For a deep dive into how the AI Assistant works, see the AI Assistant page.



Can I manage my schema through GS SQL?

Yes. GS SQL includes full DDL (Data Definition Language) support. You can CREATE, ALTER, and DROP over 15 entity types — including templates (tables), cycles, rollup calendars, stream groups, time filters, units, catalogs, delete profiles, runnables, connections, JDBC imports, views, materialized views, dashboards, and entity diagrams. All DDL statements support IF [NOT] EXISTS clauses and FOLDER_PATH for organizational placement.

Templates support typed columns with REFERENCES for foreign keys, DERIVED AS for formula-based streams, and configurable rollup methods. Use RECONCILE NOW after altering a template to propagate changes to every linked component with zero downtime — queries keep working and data keeps flowing throughout the process.

The AI Assistant can also execute DDL, so you can describe a data model in natural language and the assistant will generate and execute the DDL statements to build it — templates, foreign keys, rollup calendars, derived streams, and all. For the full DDL reference, see the GS SQL DDL documentation.



What is MCP and how do I use it with GroveStreams? (Beta)

MCP support is currently in beta. MCP — the Model Context Protocol — is a standard interface that lets external AI agents (Claude Desktop, Claude Code, Cursor, ChatGPT Desktop, and any MCP-compatible client) connect to GroveStreams natively. The agent gets four tools: describe_org for orientation, run_gsql for direct GS SQL execution, ask_grovestreams for natural-language delegation to the GroveStreams AI Assistant, and send_samples for Temporal Wire ingestion. It also gets read-only access to your help docs and per-org templates / dashboards / saved queries via MCP Resources, so it grounds itself on real GroveStreams content instead of hallucinating syntax. Authentication is per-user via OAuth 2.1 with PKCE. Full details: developers/mcp.html.



How is MCP different from the ODBC/JDBC adapter?

ODBC and MCP solve different problems and most teams use both. ODBC is your application's data driver — the runtime path your BI tool, dashboard, or app code uses to read and write GroveStreams data. Same engine, same RBAC, different transport. MCP is your AI's GroveStreams partner — the development-time path your AI agent uses to design schemas, author queries, build dashboards, and troubleshoot derivations. ODBC for your app, MCP for your AI.



Does MCP require a separate subscription?

No. MCP uses the existing LLM token infrastructure for ask_grovestreams calls and the standard query metering for run_gsql and send_samples. MCP usage is shown as a separate line item on your billing page so you can see exactly what your AI integrations cost. A per-session token budget (default 1,000,000 tokens) acts as a runaway guard.



Which AI clients work with GroveStreams MCP?

Any client implementing MCP spec 2025-11-25 over Streamable HTTP with OAuth 2.1 + PKCE. That includes Claude Desktop, Claude Code, Cursor, ChatGPT Desktop, and a growing list of community clients. The MCP developer reference has copy-paste config snippets for the major clients.



Can my organization disable MCP?

Yes. MCP is off by default. Owners and admins enable it from the AI Assistant & MCP tab in Organization Settings: a master toggle, per-tool exposure checkboxes (run_gsql / ask_grovestreams / send_samples), and an MCP SQL Policy that fences what SQL agents are allowed to run. The MCP SQL Policy applies to all SQL routed through MCP — including SQL the AI Assistant runs internally during ask_grovestreams — so admins can safely expose the assistant without worrying that an external agent could smuggle DDL or DML through it.



How much functionality is exposed in the GroveStreams' HTTP REST and MQTT APIs?

Almost all of it.

The entire web based user interface utilizes only the GroveStreams APIs for non-static page data. A popular way to become familiar with the GroveStreams HTTP API is to use the Google Chrome browser and hit F12 to monitor all HTTP calls from the browser to GroveStreams.com.

Feel free to design your own user interface using our API.



Does GroveStreams Support Custom Branding?

Yes. GroveStreams supports custom branding with your own logo and a branded subdomain (e.g., yourcompany.grovestreams.com). A "Powered by GroveStreams" attribution will appear within the application.

See the GroveStreams Website Guide for more information about custom branding.

Contact us at info@grovestreams.com for inquiries about licensing an entire GroveStreams cluster.