Building a custom Grafana data source plugin

A custom Grafana data source plugin connects Grafana to an internal API or database that no built-in data source covers. This page explains the build decisions, the effort drivers and how to keep the plugin working across Grafana releases.

On this page

When an internal system needs its own custom Grafana data source plugin

A custom data source plugin is the right route when an internal API or database holds operational data that teams need in Grafana and no existing data source reaches it cleanly. Before writing code, confirm that the system cannot be exposed through a supported data source such as a SQL database, a JSON or HTTP API source, or a time-series store that Grafana already reads. If none of those fit, a custom plugin covers four things: scaffolding with create-plugin, a Go backend that lets alerting and shared dashboards query the system on the server side, authentication handling for the internal service, and ongoing maintenance across Grafana releases. The plugin is a separate artifact from Grafana itself. The Grafana docs describe plugins as their own licensing category, which matters because Grafana Labs relicensed Grafana, Loki and Tempo to AGPLv3 on April 20, 2021, while plugins and SDKs kept other licenses, according to the Grafana Labs licensing page. Your organization, or the partner it engages, builds and owns that code, so the license, source control and support obligations sit with you.

Ownership also determines who carries the work after launch. Someone must decide who holds the repository, who reviews changes to the query model and who answers when the internal API changes its schema. Ask the team that owns the source system whether it will publish a stable contract for the endpoints or tables the plugin will read. Confirm which Grafana versions your instances run and how quickly they move, because the upgrade guidance describes minor releases every other month and each minor release supported for 9 months, which sets the pace at which the plugin must be retested. Identify the authentication model early, since the answer decides whether credentials live in the plugin's secure settings, whether the Grafana server forwards user identity, or whether a service account is used. Each choice changes what must be tested and documented. Plan these decisions before the first scaffold is generated, because they are much harder to change once dashboards depend on the plugin's query format.

What a custom data source plugin does inside Grafana

A custom data source plugin is a set of parts that each handle one job between a user's dashboard and your internal system. The parts share one contract: the configuration page supplies connection details, and the query path turns every panel request into a call your system can answer.

Configuration page

This is the screen where an administrator enters the internal endpoint, authentication method and any custom settings. Values saved here are passed to the backend, so secrets should be stored as secure JSON fields rather than plain configuration. Check who can open this page, because on most installations any editor who can reach it can see the non-secret settings. Confirm the current options with the Grafana plugin developer documentation for your target version.

Query editor

The query editor is the form users fill in when they build a panel query against your system. It defines which fields, filters, time ranges and variables a user can pick, so its design decides how much of your data model is exposed. Keep the editor limited to what your data can answer efficiently, and validate inputs before they reach the internal API. Confirm the editor components and their props in the plugin SDK documentation for your version.

Query handling

Query handling converts the query model, the selected time range and any dashboard variables into requests to the internal system. This is where pagination, timeouts, rate limits and the mapping of results into data frames are decided. Test it with empty results, large result sets and malformed responses, since a single unhandled case can break every panel on a dashboard. Confirm the frame types and transformation helpers in the Grafana plugin developer documentation.

Go backend for server-side queries

A Go backend runs queries on the Grafana server rather than in the user's browser. This is what lets alert rules evaluate against your system and lets shared dashboards and service accounts return data without each viewer holding credentials. The backend also centralizes the connection to your internal API, so network paths and secrets stay on the server. Plan for the build, signing and testing work this adds, and confirm the backend SDK details for your target version.

Health checks

A health check is the test Grafana runs when someone clicks Save and test on the data source. A useful check contacts the internal system with the configured credentials and confirms that the expected endpoint responds, and it should return a clear message when authentication fails. Keep the check lightweight, because it runs whenever an administrator saves settings. Confirm how health checks are implemented for backend plugins in the Grafana plugin developer documentation.

Packaging that Grafana loads

Packaging is the set of files Grafana reads at startup: the plugin metadata, the compiled frontend, the Go binaries for each platform and the signature. The plugin ID and the directory it sits in determine whether Grafana loads it, and unsigned private plugins need explicit configuration to run. Decide early which operating systems and architectures you build for, since the backend must match the Grafana host. Confirm the packaging layout and signing requirements for your Grafana version before you build.

Which design choices shape the plugin

This table compares the configuration decisions that set a custom data source plugin's architecture, security model and sharing scope. Read each row against your internal system's access model, because the first answer often determines the rest. The main takeaway is that identity pass-through depends on how your Grafana instance authenticates users, so confirm that before choosing a design.

DecisionOptionsWhen each fits
Frontend or backendFrontend-only plugin calling the API from the browser, or a Go backend that proxies requests from the Grafana serverFrontend-only suits simple, public, CORS-enabled APIs. A Go backend is needed for alerting, server-side secrets, private networks and shared dashboards that run without a user's browser session.
Authentication to the internal systemService account, static API key, OAuth token exchange, or passing the signed-in user's identityA service account suits shared read-only dashboards. Identity pass-through fits systems that enforce per-user permissions, but it works only if the Grafana auth setup forwards a usable identity or token.
Identity pass-through prerequisitesEnterprise identity providers and auth methods available in the edition you runThe Grafana authentication docs list which providers and methods each edition supports. Confirm your edition and login method before designing around user identity.
Secret storageData source secure JSON fields, environment variables, or an external secrets storeSecure JSON fields keep credentials out of the browser and dashboards. External stores fit organizations that already rotate credentials centrally, but add a dependency the backend must reach at query time.
Query modelFree-form query text, structured fields per query type, or a hybrid of bothStructured fields suit users without query language skills and make validation simple. Free-form text suits experienced users and systems with rich query languages, but needs input limits and clear error handling.
Alerting and template variablesQueries supported for alerting only in the backend, with variable lookups from the same endpointsTeams that need alert rules on this source must plan backend queries from the start. Dashboards that filter by variables need a lookup path that returns quickly and respects permissions.
Sharing scopeSingle Grafana instance, or a plugin distributed to several instances or teamsA single instance keeps versioning simple. Shared plugins need consistent versions, signing per instance and a release process that tracks Grafana upgrades across every environment.
Release ownershipInternal team maintains the plugin, or a partner maintains it under a support agreementOwnership should cover compatibility testing for each Grafana minor and patch release, dependency updates and credential rotation. Ask who runs these checks and how often.

Build sequence and the output of each step

The sequence moves from agreeing what the data source returns, through a scaffold and a working Go backend, to a provisioned staging instance with documented operations. Each step ends with an artifact your team can inspect before the next one starts.

  1. Define the data contract with system owners

    Your team and the owners of the internal API or database agree on what the plugin asks for and what it gets back. This covers the query model (fields, filters, time range handling, pagination and row limits), the response shape each panel type expects, error codes, and which service account the plugin will use. The owners of the system should sign off on the written contract before any code is written. Done means a short written query contract that names every query field, its type, and an example request and response from the real system, reviewed by its owner.

  2. Scaffold the plugin with create-plugin

    A developer generates the plugin project from Grafana's create-plugin scaffolding tool, choosing the data source template and the backend option so the Go server is part of the project from the start. The scaffold sets the plugin ID, type, and the frontend and backend build tooling. Confirm the exact template options and the current generator command against the Grafana plugin documentation for your Grafana version, since the tooling changes over time. Done means the scaffold builds and loads in a local Grafana without errors, with the plugin ID and name set to your organization's values.

  3. Build the frontend configuration and query editor

    A frontend developer implements the configuration page where an administrator enters the internal system's URL and non-secret settings, and the query editor where dashboard authors choose fields and filters from the contract. Validation runs in the browser so authors see errors before a query is sent. Keep the query model in one typed definition shared with the backend. Done means an author can build a query in a panel, see the query sent to the backend in browser developer tools, and save a data source that passes the configuration form's own validation.

  4. Add the Go backend and its health check

    A backend developer implements the Go code that receives queries from Grafana, calls the internal system, converts results into Grafana data frames, and returns errors in a form Grafana can display. The data source must implement a health check that Grafana runs when someone presses Save and Test, so misconfiguration shows up at setup time. Done means the health check returns a clear success or failure message against a test endpoint, and a dashboard query returns data frames that render in a time series and a table panel.

  5. Implement authentication and secrets handling

    A security-focused developer adds the credential flow the internal system requires, such as an API key, a service account, or an OAuth token exchange. Secrets go into Grafana's encrypted secure JSON fields, never into the plugin's frontend code or plain configuration. The backend should refuse requests when credentials are missing and must not log tokens or request headers. Confirm which secret storage option your Grafana deployment uses and how the credential is rotated. Done means a review of the code and a test run show that credentials are never returned to the browser, never appear in logs, and that an expired or revoked credential produces a clear error.

  6. Test queries in dashboards and alert rules

    The team checks the plugin in the places it will be used: dashboards, template variables, shared dashboards viewed by users with different permissions, and Grafana Alerting rules that evaluate the data source on a schedule. Alerting depends on the backend returning consistent, numeric or time-series data frames, so this step checks the output shape that alert rules need. Automated tests should cover the query model and backend handlers. Done means a dashboard and an alert rule both evaluate against the staging internal system, and a test alert fires and resolves as expected.

  7. Package and provision the plugin into staging

    The team builds a release of the plugin and installs it on a staging Grafana instance, then provisions the data source configuration from files rather than through the UI, so the setup can be repeated. Signing is required for private plugins to load without allowing unsigned plugins. That process is covered on the signing page for private Grafana plugins. Done means the staging Grafana starts with the plugin loaded and the data source provisioned from version-controlled files, and the health check passes after a restart.

  8. Document operations and the upgrade path

    The team writes the operating guide: the data contract and its version, the list of Grafana versions the plugin has been tested against, the credential rotation procedure, the owners of each part, and the steps to repeat the build and test when Grafana or the internal system changes. Plan a recurring check of the plugin against each Grafana release because plugin APIs change across major versions. Done means a runbook exists in version control, a named owner has reviewed it, and the team has run the upgrade check once against the next Grafana version in a test instance.

What drives the effort and cost of a custom data source

This table lists the factors that change how much work a custom Grafana data source takes and how to keep each one contained. Read it before requesting a quote, because each driver shifts scope in a different direction. The main takeaway is that query surface, authentication and whether alerting must work account for most of the difference between a small plugin and a long engagement.

DriverWhy it changes the workHow to reduce it
Number and complexity of query typesEach query type needs its own editor fields, request shape, response mapping and tests. Dynamic variables and streaming add further design work.Agree a short list of query types in the scope document. Defer rarely used endpoints to a later release.
Authentication model of the internal systemAPI keys, OAuth client credentials, mutual TLS and per-user tokens each need different config screens, secure storage and token refresh logic in the backend.Prefer a single service account for the data source. Confirm early whether user-level identity must pass through to the internal system.
Whether alerting must workAlerting runs on the backend, so the Go backend must implement health checks and query handling that work without a browser session. This adds code and test cases.Decide which queries must be alertable before design starts. Keep non-alerting exploration queries in the frontend only where that is acceptable.
Quality and stability of the internal APIMissing pagination, inconsistent error formats, slow responses or unversioned schemas force retry, timeout and mapping logic in the plugin.Ask the API owners for a documented schema and stable error codes. Fix known defects in the API before the plugin depends on them.
Number of Grafana instances and editions in scopeEach instance needs its own install, provisioning and signing or configuration. Enterprise-only features may change which auth options the plugin can rely on.Standardize on one Grafana version range for the first release. Confirm which edition each instance runs before scoping.
Test coverage with the plugin test toolingFrontend tests, backend unit tests and end-to-end checks against a running Grafana each add build and maintenance time. Gaps tend to surface during upgrades.Require a defined test set in the statement of work. Include at least one end-to-end run against the target Grafana versions.
Team Go and TypeScript skillsThe frontend is TypeScript and the alerting-capable backend is Go. A team strong in only one language will need more review time or outside support for the other.Assign a named owner for each language. Ask the partner to state which parts they build and which your team reviews.

When a frontend-only plugin is enough and when it is not

A small team that builds panels for its own dashboards on one instance can often start with a frontend-only data source, provided the internal API accepts requests from the browser. In this design the plugin code and its queries run in each user's browser, so the internal system sees calls that originate from the Grafana user interface.

  • Backend need: Usually none for reading data in dashboards, as long as the API can be called directly from the browser.
  • Browser exposure: Any token or key the plugin uses is available to the browser session, so confirm which credentials the API accepts from a browser and whether they can be scoped to read-only access.
  • CORS: The internal API must allow the Grafana origin and the headers the plugin sends. Confirm this with the API owner before the build starts.
  • What the choice removes: The Go toolchain, backend binaries for each operating system and architecture, and the server-side test work that a backend adds.
  • Limit to watch: Any need for a server-side query path, a service identity or background evaluation moves the design to the next tab.

Before committing to this path, check the requests the plugin makes in the browser developer tools on a test instance and confirm that no secret appears in them.

How the plugin connects to the rest of the Grafana platform

A custom data source plugin is only as useful as the Grafana instance around it. The cards below cover the platform services that must be configured on both sides, from sign-in and provisioning to alerting, high availability and the internal system's own identity and secrets.

Authentication and identity

Users reach the plugin through Grafana's sign-in, so the login method decides who can open dashboards that query your internal API. Open source supports LDAP, generic OAuth, Entra ID, Okta, GitHub, GitLab, Google OAuth, auth proxy and JWT. SAML, team sync, active sync and SCIM are Grafana Enterprise and Grafana Cloud features. Confirm which method your organization requires before you choose the edition.

Provisioning at startup

Define the data source and the plugin installation as YAML or JSON files loaded when Grafana starts, so every instance receives the same configuration. Store the files in version control and keep credentials out of them by referencing environment variables or secrets. Grafana also documents Terraform and Git Sync as as-code options, which you should evaluate against your change process.

Private plugin signing

A plugin that is not signed will not load unless unsigned plugins are explicitly allowed, which is a weaker security posture. The signing workflow ties the plugin to the root URLs of each instance, so every new hostname or environment needs its own signature. Plan signing into your release pipeline before the first deployment, and re-sign whenever those URLs change.

Alerting and notification routing

Backend-backed data sources can be used in Grafana Alerting rules, which means the plugin's query behavior, timeouts and error messages affect whether alerts fire correctly. Define contact points and notification policies for the teams that own the internal system, and test that a failing query produces a visible alert. Confirm that your alert rules evaluate in the expected place when the plugin is installed on several nodes.

High availability and shared database

High availability uses two or more active-active Grafana servers behind a load balancer, sharing a MySQL 8.0 or later or PostgreSQL 12 or later database. Alerting needs additional configuration to avoid duplicate notifications, and Grafana Live has limitations in HA. Install the plugin identically on every node, and test that dashboards and alerts behave the same whichever node serves the request.

Internal identity and secrets

The plugin's backend must obtain credentials for your internal API from a service you already run, such as a vault or an identity provider with service accounts. Decide which identity the plugin uses, whether it is a shared service account or per-user delegation, and how tokens are rotated. Ask the owner of the internal system to confirm scopes, token lifetimes and audit logging before you write the authentication code.

How to keep a custom plugin working across Grafana releases

Plan the maintenance of a custom data source plugin around the Grafana release rhythm, because the support window for each version sets how often your team has to test and re-ship. According to the Grafana upgrade guidance, major releases arrive roughly once a year in April or May, minor releases about every other month, and patch releases at least monthly. Each minor release is supported for 9 months, and the last minor release of a major version for 15 months. Recent examples show the cadence: Grafana 12.0.0 shipped on May 5, 2025, while 13.1.0 followed on July 1, 2026 and 13.2.0 on August 18, 2026, according to the grafana/grafana releases page. Before you commit a maintenance budget, confirm the current support windows in the Grafana upgrade guide, since these are the terms your plan depends on.

Build a repeatable loop rather than reacting to each release. Stand up a staging Grafana that matches production in version, database and plugin list, then upgrade it to each new minor release before production. Run your data source's query editor, health check and alerting path against it, and check the Grafana release notes for deprecations in the plugin APIs and the @grafana/* packages your package.json pins. Any change to the plugin code, dependencies or plugin.json means a fresh build, a new signature for your signing configuration, and a version bump so instances pick up the new bundle. Regression testing is the largest recurring cost, because each release can break the Go backend, the frontend bundle or both, and the test suite must cover the authentication path your internal API uses.

Questions teams ask before building a custom data source plugin

How much does a custom Grafana data source plugin cost to build?

The cost depends on the scope agreed in writing, not on a standard price. DeployOpen does not publish a price list, and a quote follows from the scope. The main components are discovery of the internal API or database, scaffolding and frontend configuration, a Go backend if alerting or shared dashboards need it, authentication handling, testing, signing and documentation, and handover. Ask the quote to show each component separately, which parts are one-time, and which recur, such as upgrades and maintenance across Grafana releases. Grafana's own pricing page lists Grafana Cloud fees, but those cover the hosted service, not the cost of building a plugin for your systems.

How long does it take to build a custom data source plugin?

Duration is set by the number of query types, the complexity of the internal API or database, the authentication model, and how many environments must be tested. A plugin with one read-only query and a simple token needs far less work than one that must support alerting, templating variables and several permission levels. Ask for a fixed-scope timeline in the written proposal, with milestones for discovery, the first working query, the backend, security review and handover. No duration is given here because none was supplied for this topic.

What does our team need to provide before the build starts?

Four things remove most of the early delay. First, API documentation or schema details for the endpoints or tables the plugin will query, including rate limits and pagination behavior. Second, a test environment that mirrors production data shapes, so queries can be verified without touching live systems. Third, a service account with read-only access scoped to the required data, plus a secure way to hand over its credentials. Fourth, a named owner who can answer questions, approve the scope and accept the plugin at handover. Without the owner, decisions stall and maintenance has no home after the build.

Can our in-house team build a custom Grafana data source plugin?

Often yes, if the team has frontend skills in TypeScript and React for the configuration and query editors, and back-end skills in Go if the plugin needs a backend. The Grafana plugin development tooling, including create-plugin scaffolding, gives a starting structure. The harder parts are secure authentication to the internal system, correct handling of errors and timeouts, testing across Grafana versions, and signing for private use. Compare the internal effort against the scope list, and check whether the people who would maintain the plugin are the same people who build it.

Do we always need a Go backend for a custom data source plugin?

No. A frontend-only data source can work when Grafana calls the target directly from the browser and the panels are used only interactively. A Go backend is needed when queries must run on the Grafana server, for example to keep credentials out of the browser, to support alert rules evaluated by the server, or to work reliably with shared dashboards and provisioned data sources. If alerting is part of the requirement, plan for a backend from the start, because adding it later changes the authentication and query path.

How should the plugin authenticate to the internal system?

Use a dedicated, read-only service identity that the Grafana server holds, rather than individual user credentials stored in dashboards. Store secrets in Grafana's secure data source settings so they are not exposed to the browser, and confirm rotation procedures before go-live. Where the internal system supports it, pass through user identity or token exchange so that access in Grafana follows the source system's permissions. Confirm with the system owner which model they accept, which scopes the account needs, and how revocation works when someone leaves.

What happens to a custom plugin when Grafana is upgraded?

Grafana releases minor versions every other month and patch releases at least monthly, and each minor release is supported for 9 months, according to Grafana's upgrade guidance. A custom plugin must be tested against each version you plan to run, because plugin APIs, the build tooling and Grafana's frontend libraries change over time. Plan a recurring test pass in a staging instance, keep the plugin's dependencies current, and assign someone to re-sign the plugin when its URLs or versions change. Ask any partner to specify the upgrade testing and whether it is included in the fixed scope or a retainer.

Can an existing data source or Grafana Labs plugin cover the need instead?

Check this first. Grafana ships built-in data sources and Grafana Labs publishes plugins for many systems, and a custom plugin is only justified when none of them reads your internal API or database with acceptable security and cost. Compare what the existing option can do for authentication, query language, alerting support and maintenance, and whether it fits your edition and licensing. Alternatively, expose the internal data through an API or database view that an existing data source can query. This comparison is usually short and avoids building a plugin you then have to maintain.

How DeployOpen scopes, builds and supports a custom data source plugin

DeployOpen starts with a written scope that names the internal API or database, the query model, the authentication method and the Grafana instances the plugin must serve. We then build, test and document the plugin inside your infrastructure, hand it over with the source and runbooks your team needs, and offer ongoing support as a retainer if you want it.

How we scope

  • Engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts.
  • The written scope names the source system, query language, data shapes and which Grafana instances need the plugin.
  • Scope records whether alerting and shared dashboards need a Go backend, and which authentication method the source accepts.

How we build

  • We scaffold the plugin with the official tooling, then add the backend and frontend query editor the scope requires.
  • Authentication handling, secret storage and error mapping are built and reviewed against the agreed security requirements.
  • Testing covers query behavior, health checks, alerting paths and the Grafana versions your estate runs, documented before release.

How we hand over

  • You receive the source code, build pipeline, signing steps and provisioning files for each target Grafana instance.
  • Documentation covers configuration, rollout steps, known limits and the checks to run after each Grafana upgrade.
  • Handover includes a walkthrough with the engineers who will maintain the plugin after the engagement closes.

How we support

  • Ongoing support, upgrades and testing against new Grafana releases are available as a retainer.
  • Retainer scope is agreed in writing and can cover plugin updates when your internal API or authentication changes.
  • Ask your DeployOpen contact to confirm response expectations and the upgrade windows included in any retainer.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.