Skip to content
Gravity Tables
All documentation

Reference

Technical FAQ

Implementation-level questions developers ask when building with Gravity Tables.

Different from the home FAQ (which answers “should I buy this?”), these are the questions developers ask while implementing.

Performance#

How many entries can a single table handle?#

Tested up to 50,000 entries on shared hosting with PHP 8.1 and 4GB RAM. Pagination is server-side; only the current page’s rows hit the client. Beyond ~50k, use the Top-N display setting (top_n_count / top_n_column, shipped in 4.2.54) to cap the rendered set, or split into per-period tables. Virtual scrolling for 10,000+ visible rows is on the 4.3 roadmap.

Does it cache anything?#

Yes, three layers:

  1. WordPress object cache (1-minute TTL on entry queries). Respects wp_cache_flush().
  2. In-memory request cache (per-request). Same query within a request returns the cached result.
  3. Browser cache for static assets (.js, .css, .svg) with the standard WordPress cache-busting query string.

Cache invalidation: edits + new entries flush the WP object cache for the affected table immediately. Manual flush via Tables → System → Flush cache or wp gt flush-cache.

Does auto-refresh hit the database every interval?#

Yes. Each refresh runs the configured query plus filter state. On heavily-trafficked pages with auto_refresh="true", dial the interval up to 60-300 seconds to spread load.

Compatibility#

Does it work with WPML / Polylang?#

Yes. Gravity Tables uses standard WordPress translation hooks (__(), esc_html__()) and a .po text domain. Field labels translate via Gravity Forms’ own translation flow.

Does it work with WooCommerce?#

The plugin works alongside WooCommerce, they don’t conflict. For WooCommerce-product-as-table use cases, see Posts Table Pro (different data source).

Does it work with Elementor / Gutenberg / Bricks / Beaver / Divi?#

Yes. The shortcode renders inside any page builder that supports WordPress shortcodes (all of them do). Native Gutenberg block shipped in v4.1.60, drop it from the inserter, pick a table from the sidebar dropdown, see the live preview right in the editor. Native Elementor widget shipped in v4.1.61 alongside. See the embed-and-customize sprint release post for the full story.

Does it work with caching plugins (WP Rocket, W3 Total Cache, LiteSpeed)?#

Yes. The plugin emits standard cache-control headers. For pages with auto_refresh="true", exclude them from full-page cache via the caching plugin’s exclude list, auto-refresh polls the database each cycle, which a fully-cached page bypasses.

Data model#

Where does the data live?#

In your WordPress database, in the standard Gravity Forms tables (wp_gf_entry, wp_gf_entry_meta). Gravity Tables doesn’t create its own entry tables.

It does create:

  • wp_gt_tables, table configurations (which form, which columns, settings)
  • wp_gt_audit, audit log (only if audit_log="true" is used somewhere)
  • wp_gt_export_audit, export log (only if audit_exports="true" is used)

These are created on plugin activation, removed on uninstall.

Can I query the entries directly via SQL?#

Yes, they live in wp_gf_entry and wp_gf_entry_meta, governed by Gravity Forms. The Gravity Tables config table (wp_gt_tables) is separate and just stores rendering preferences.

Are entries soft-deleted or hard-deleted?#

Bulk delete via Gravity Tables uses GFAPI::delete_entry(), which is the standard Gravity Forms delete (entries move to trash, then are purged on the next cron). Behavior is consistent with deleting from the GF admin entries screen.

Security#

Is the inline editing safe?#

Every edit goes through:

  1. Nonce verification (rotated per page load)
  2. Capability check (does this user have edit access for this column?)
  3. Per-row permission check (does this user own the row, if filter_by_user="true"?)
  4. Gravity Forms validation (does the new value pass the field’s rules?)

All four happen server-side. Client-side UI is for UX only, bypassing the UI doesn’t bypass the checks.

Is data sent to your servers?#

No. The plugin sends nothing to wpgravitytables.com or to TableCrafter. All data stays in your WordPress database. There are no analytics pings, no opt-out telemetry, no “anonymous usage statistics”.

The only exception: Freemius licence verification pings Freemius’s servers (their domain) periodically with your domain + licence key. That’s required for licence enforcement.

CSV / Excel injection?#

Cells starting with =, +, -, or @ get a ' auto-prefix on CSV export so Excel renders them as text instead of evaluating as formulas. Standard defense against CSV-injection attacks.

API#

Is there a REST API?#

Yes, /wp-json/gt/v1/. Endpoints:

  • GET /tables/{id}/entries?filter=...&page=..., paginated entries (server applies the same role + per-user gates)
  • POST /tables/{id}/entries/{entry_id}/edit, inline edit (requires nonce + capability)
  • POST /tables/{id}/bulk, bulk action
  • POST /tables/{id}/export, start an export job
  • GET /audit?table_id=..., audit log entries (admin-only)

All endpoints require WordPress authentication (cookies or application passwords).

Can I extend the bulk actions?#

Yes, see PHP hooks → bulk action registration.

Can I subscribe to inline edits from JavaScript?#

Yes, see JavaScript events.

Common gotchas#

My table renders but is empty#

Most likely cause: an active filter narrowed the results to zero. Check filter_by_user="true" (does the current user have any entries?) or hard-coded filter parameters. Append ?gt_debug=1 to see the query the plugin actually ran.

My export is missing rows#

Exports respect active filters. If you have filter_by_user="true" on the table, the export will only include the current user’s rows (which is usually the intended behavior). To export all rows regardless of user filter, use the admin entries-export from Gravity Forms directly.

The “Add New Entry” button isn’t showing#

Three layers gate it:

  1. allow_add="true" set in the shortcode
  2. Current user has the gravityforms_create_entries capability
  3. Current user has any custom capability set in add_permissions

All three must be true. Use ?gt_debug=1 to see which check failed.