diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index d772e454a06b5a9d4244fb79fd18daea635908fd..3f7ac3445044ddd4a7e38d5cc3000e5fa5c587a0 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -502,7 +502,7 @@ def self.authorization_scopes
description: 'Grafana integration details for the project.',
deprecated: {
reason: 'Feature was removed in 16.0. Always returns null',
- milestone: '18.3'
+ milestone: '18.5'
}
field :snippets, Types::SnippetType.connection_type,
diff --git a/db/docs/grafana_integrations.yml b/db/docs/deleted_tables/grafana_integrations.yml
similarity index 74%
rename from db/docs/grafana_integrations.yml
rename to db/docs/deleted_tables/grafana_integrations.yml
index 24d7bb0430ad9524252943c6cf22ac28662b0389..403c78ce862f160fcf0d6735240ec47347621d2f 100644
--- a/db/docs/grafana_integrations.yml
+++ b/db/docs/deleted_tables/grafana_integrations.yml
@@ -11,3 +11,5 @@ gitlab_schema: gitlab_main_org
sharding_key:
project_id: projects
table_size: small
+removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199243
+removed_in_milestone: '18.5'
diff --git a/db/post_migrate/20250924071156_remove_grafana_integrations_fk_project_id.rb b/db/post_migrate/20250924071156_remove_grafana_integrations_fk_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6c084f3f06dca2a0eba366af5e1d93e6339ee8c3
--- /dev/null
+++ b/db/post_migrate/20250924071156_remove_grafana_integrations_fk_project_id.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class RemoveGrafanaIntegrationsFkProjectId < Gitlab::Database::Migration[2.3]
+ milestone '18.5'
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_18d0e2b564'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(
+ :grafana_integrations,
+ column: :project_id,
+ on_delete: :cascade,
+ name: CONSTRAINT_NAME
+ )
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(
+ :grafana_integrations,
+ :projects,
+ column: :project_id,
+ on_delete: :cascade,
+ name: CONSTRAINT_NAME
+ )
+ end
+end
diff --git a/db/post_migrate/20250924071302_remove_grafana_integrations.rb b/db/post_migrate/20250924071302_remove_grafana_integrations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ae47e1d346d1747275844f24d74cbbbea22aba9a
--- /dev/null
+++ b/db/post_migrate/20250924071302_remove_grafana_integrations.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class RemoveGrafanaIntegrations < Gitlab::Database::Migration[2.3]
+ milestone '18.5'
+
+ def up
+ drop_table :grafana_integrations
+ end
+
+ def down
+ execute <<~SQL
+ CREATE TABLE grafana_integrations (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ encrypted_token character varying(255) NOT NULL,
+ encrypted_token_iv character varying(255) NOT NULL,
+ grafana_url character varying(1024) NOT NULL,
+ enabled boolean DEFAULT false NOT NULL
+ );
+
+ CREATE SEQUENCE grafana_integrations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ ALTER SEQUENCE grafana_integrations_id_seq OWNED BY grafana_integrations.id;
+
+ ALTER TABLE ONLY grafana_integrations ALTER COLUMN id SET DEFAULT nextval('grafana_integrations_id_seq'::regclass);
+
+ ALTER TABLE ONLY grafana_integrations ADD CONSTRAINT grafana_integrations_pkey PRIMARY KEY (id);
+
+ CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING btree (enabled) WHERE (enabled IS TRUE);
+
+ CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
+ SQL
+ end
+end
diff --git a/db/schema_migrations/20250924071156 b/db/schema_migrations/20250924071156
new file mode 100644
index 0000000000000000000000000000000000000000..d31eb24786e0c063b65fca448e4dc6d5076e63bd
--- /dev/null
+++ b/db/schema_migrations/20250924071156
@@ -0,0 +1 @@
+96431864166b88fa736d6730fc3429c696084b32f64db695ed22474f02466ba0
\ No newline at end of file
diff --git a/db/schema_migrations/20250924071302 b/db/schema_migrations/20250924071302
new file mode 100644
index 0000000000000000000000000000000000000000..dbf08c4f8a43815a538da45c56a72071b6e27f95
--- /dev/null
+++ b/db/schema_migrations/20250924071302
@@ -0,0 +1 @@
+aa36dc97300cb6cbc57d12367f40fa22046920a248829b007ff6583936cd62ff
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 69bf1c18690705e861fad26c47b9faa881d1a384..fee6c69b3c182e918d4a31aaeaab81abbea48649 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -39494,10 +39494,6 @@ CREATE INDEX index_gpg_signatures_on_gpg_key_subkey_id ON gpg_signatures USING b
CREATE INDEX index_gpg_signatures_on_project_id ON gpg_signatures USING btree (project_id);
-CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING btree (enabled) WHERE (enabled IS TRUE);
-
-CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
-
CREATE INDEX index_group_crm_settings_on_group_id ON group_crm_settings USING btree (group_id);
CREATE INDEX index_group_crm_settings_on_source_group_id ON group_crm_settings USING btree (source_group_id);
@@ -49518,9 +49514,6 @@ ALTER TABLE ONLY audit_events_streaming_http_group_namespace_filters
ALTER TABLE ONLY cluster_providers_aws
ADD CONSTRAINT fk_rails_18983d9ea4 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
-ALTER TABLE ONLY grafana_integrations
- ADD CONSTRAINT fk_rails_18d0e2b564 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY queries_service_pings
ADD CONSTRAINT fk_rails_18dedc7d8e FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index 7b29d9d71bd838ec4566902501f871db05c49feb..fcb641e19a7cab25ce0beef4705541d1d4406962 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -38581,7 +38581,7 @@ Project-level settings for product analytics provider.
| `forksCount` | [`Int!`](#int) | Number of times the project has been forked. |
| `fullPath` | [`ID!`](#id) | Full path of the project. |
| `googleCloudArtifactRegistryRepository` {{< icon name="warning-solid" >}} | [`GoogleCloudArtifactRegistryRepository`](#googlecloudartifactregistryrepository) | **Introduced** in GitLab 16.10. **Status**: Experiment. Google Artifact Registry repository. Returns `null` if the GitLab instance is not a SaaS instance. |
-| `grafanaIntegration` {{< icon name="warning-solid" >}} | [`GrafanaIntegration`](#grafanaintegration) | **Deprecated** in GitLab 18.3. Feature was removed in 16.0. Always returns null. |
+| `grafanaIntegration` {{< icon name="warning-solid" >}} | [`GrafanaIntegration`](#grafanaintegration) | **Deprecated** in GitLab 18.5. Feature was removed in 16.0. Always returns null. |
| `group` | [`Group`](#group) | Group of the project. |
| `hasJiraVulnerabilityIssueCreationEnabled` | [`Boolean!`](#boolean) | Indicates whether Jira issue creation from vulnerabilities is enabled. |
| `httpUrlToRepo` | [`String`](#string) | URL to connect to the project via HTTPS. |
diff --git a/spec/migrations/20250924071156_remove_grafana_integrations_fk_project_id_spec.rb b/spec/migrations/20250924071156_remove_grafana_integrations_fk_project_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..109aeb2747990c93f068576345fe69b250c5f03c
--- /dev/null
+++ b/spec/migrations/20250924071156_remove_grafana_integrations_fk_project_id_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveGrafanaIntegrationsFkProjectId, feature_category: :observability do
+ include Database::TableSchemaHelpers
+
+ let(:table_name) { :grafana_integrations }
+
+ it 'drops the projects foreign key constraint' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect_foreign_key_to_exist(table_name, described_class::CONSTRAINT_NAME)
+ }
+
+ migration.after -> {
+ expect_foreign_key_not_to_exist(table_name, described_class::CONSTRAINT_NAME)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20250924071302_remove_grafana_integrations_spec.rb b/spec/migrations/20250924071302_remove_grafana_integrations_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3f043b7d0f0dbc17cc7a3689786fea36daae2e55
--- /dev/null
+++ b/spec/migrations/20250924071302_remove_grafana_integrations_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveGrafanaIntegrations, feature_category: :observability do
+ include Database::TableSchemaHelpers
+
+ let(:table_name) { :grafana_integrations }
+ let(:column_attributes) do
+ [
+ { name: 'id', sql_type: 'bigint', null: false, default: nil },
+ { name: 'project_id', sql_type: 'bigint', null: false, default: nil },
+ { name: 'created_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'updated_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'encrypted_token', sql_type: 'character varying(255)', null: false, default: nil },
+ { name: 'encrypted_token_iv', sql_type: 'character varying(255)', null: false, default: nil },
+ { name: 'grafana_url', sql_type: 'character varying(1024)', null: false, default: nil },
+ { name: 'enabled', sql_type: 'boolean', null: false, default: 'false' }
+ ]
+ end
+
+ it 'drops the grafana_integrations table' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect_table_columns_to_match(column_attributes, table_name)
+ expect_primary_keys_after_tables([table_name])
+ expect_index_to_exist('index_grafana_integrations_on_enabled')
+ expect_index_to_exist('index_grafana_integrations_on_project_id')
+ }
+
+ migration.after -> {
+ expect(connection.table_exists?(table_name)).to be(false)
+ }
+ end
+ end
+end