diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.styled.tsx b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.styled.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..252b972d8af7a364321124713c4f4cd474d55d8f
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.styled.tsx
@@ -0,0 +1,18 @@
+import styled from "@emotion/styled";
+import { color } from "metabase/lib/colors";
+import NumericInput from "metabase/core/components/NumericInput";
+
+export const TimeInputRoot = styled.div`
+  display: flex;
+  align-items: center;
+  gap: 0.625rem;
+`;
+
+export const TimeInput = styled(NumericInput)`
+  width: 3.125rem;
+  text-align: center;
+`;
+
+export const TimeInputMessage = styled.div`
+  color: ${color("text-dark")};
+`;
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.tsx b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..976acfdfb08a5194e42cd6bc18444a4431078511
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/CacheTimeInput.tsx
@@ -0,0 +1,53 @@
+import React, { FocusEvent, useCallback } from "react";
+import { t } from "ttag";
+import {
+  TimeInputMessage,
+  TimeInputRoot,
+  TimeInput,
+} from "./CacheTimeInput.styled";
+
+export interface CacheTimeInputProps {
+  id?: string;
+  name?: string;
+  value?: number;
+  message?: string;
+  error?: boolean;
+  onChange?: (value?: number) => void;
+  onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
+}
+
+const CacheTimeInput = ({
+  id,
+  name,
+  value,
+  message,
+  error,
+  onChange,
+  onBlur,
+}: CacheTimeInputProps): JSX.Element => {
+  const handleChange = useCallback(
+    (value?: number) => {
+      onChange?.(value !== 0 ? value : undefined);
+    },
+    [onChange],
+  );
+
+  return (
+    <TimeInputRoot>
+      {message && <TimeInputMessage>{message}</TimeInputMessage>}
+      <TimeInput
+        id={id}
+        name={name}
+        value={value}
+        placeholder="24"
+        error={error}
+        fullWidth
+        onChange={handleChange}
+        onBlur={onBlur}
+      />
+      <TimeInputMessage>{t`hours`}</TimeInputMessage>
+    </TimeInputRoot>
+  );
+};
+
+export default CacheTimeInput;
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/index.ts b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3abbcacd3318592608e36398923c76dee9a8d798
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/CacheTimeInput/index.ts
@@ -0,0 +1 @@
+export { default } from "./CacheTimeInput";
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/DatabaseCacheTimeField.tsx b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/DatabaseCacheTimeField.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..01a242eeb335ead26b962ebbd88b94603cff2c10
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/DatabaseCacheTimeField.tsx
@@ -0,0 +1,58 @@
+import React, { useCallback } from "react";
+import { useField, useFormikContext } from "formik";
+import { jt, t } from "ttag";
+import { useUniqueId } from "metabase/hooks/use-unique-id";
+import Link from "metabase/core/components/Link/Link";
+import FormField from "metabase/core/components/FormField";
+import { DatabaseValues } from "metabase/databases/types";
+import DatabaseCacheTimeInput from "../DatabaseCacheTimeInput";
+
+const FIELD = "cache_ttl";
+const SECTION = "advanced-options";
+
+const DatabaseCacheTimeField = () => {
+  const id = useUniqueId();
+  const [{ value, onBlur }, { error, touched }, { setValue }] = useField(FIELD);
+  const { values } = useFormikContext<DatabaseValues>();
+
+  const handleChange = useCallback(
+    (value?: number) => setValue(value != null ? value : null),
+    [setValue],
+  );
+
+  if (!values.details[SECTION]) {
+    return null;
+  }
+
+  return (
+    <FormField
+      title={t`Default result cache duration`}
+      description={<DatabaseCacheTimeDescription />}
+      htmlFor={id}
+      error={touched ? error : undefined}
+    >
+      <DatabaseCacheTimeInput
+        id={id}
+        name={FIELD}
+        value={value ?? undefined}
+        error={touched && error != null}
+        onChange={handleChange}
+        onBlur={onBlur}
+      />
+    </FormField>
+  );
+};
+
+const DatabaseCacheTimeDescription = (): JSX.Element => {
+  return (
+    <div>
+      {jt`How long to keep question results. By default, Metabase will use the value you supply on the ${(
+        <Link key="link" to="/admin/settings/caching">
+          {t`cache settings page`}
+        </Link>
+      )}, but if this database has other factors that influence the freshness of data, it could make sense to set a custom duration. You can also choose custom durations on individual questions or dashboards to help improve performance.`}
+    </div>
+  );
+};
+
+export default DatabaseCacheTimeField;
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/index.ts b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d4f08ab04fcac0e7ca46c1a4eb5131ad64546cef
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeField/index.ts
@@ -0,0 +1 @@
+export { default } from "./DatabaseCacheTimeField";
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.styled.tsx b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.styled.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..7ab712c3863241e561bd3a9f06dd68cc30e8edc3
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.styled.tsx
@@ -0,0 +1,7 @@
+import styled from "@emotion/styled";
+
+export const TimeInputRoot = styled.div`
+  display: flex;
+  align-items: center;
+  gap: 1rem;
+`;
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.tsx b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..a2e935a74190a6c450342ea058c6d485c8f60589
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/DatabaseCacheTimeInput.tsx
@@ -0,0 +1,62 @@
+import React, { FocusEvent, useCallback, useState } from "react";
+import { t } from "ttag";
+import Select, { SelectChangeEvent } from "metabase/core/components/Select";
+import CacheTimeInput from "../CacheTimeInput";
+import { TimeInputRoot } from "./DatabaseCacheTimeInput.styled";
+
+const CACHE_OPTIONS = [
+  { name: t`Use instance default (TTL)`, value: false },
+  { name: t`Custom`, value: true },
+];
+
+const DEFAULT_CACHE_TIME = 24;
+
+export interface DatabaseCacheTimeInputProps {
+  id?: string;
+  name?: string;
+  value?: number;
+  error?: boolean;
+  onChange?: (value?: number) => void;
+  onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
+}
+
+const DatabaseCacheTimeInput = ({
+  id,
+  name,
+  value,
+  error,
+  onChange,
+  onBlur,
+}: DatabaseCacheTimeInputProps): JSX.Element => {
+  const [isCustom, setIsCustom] = useState(value != null);
+
+  const handleChange = useCallback(
+    ({ target: { value: isCustom } }: SelectChangeEvent<boolean>) => {
+      setIsCustom(isCustom);
+      onChange?.(isCustom ? DEFAULT_CACHE_TIME : undefined);
+    },
+    [onChange],
+  );
+
+  return (
+    <TimeInputRoot>
+      <Select
+        value={isCustom}
+        options={CACHE_OPTIONS}
+        onChange={handleChange}
+      />
+      {isCustom && (
+        <CacheTimeInput
+          id={id}
+          name={name}
+          value={value}
+          error={error}
+          onChange={onChange}
+          onBlur={onBlur}
+        />
+      )}
+    </TimeInputRoot>
+  );
+};
+
+export default DatabaseCacheTimeInput;
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/index.ts b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac2d66252da102b5ca3bcbce91f01a9a587c31de
--- /dev/null
+++ b/enterprise/frontend/src/metabase-enterprise/caching/components/DatabaseCacheTimeInput/index.ts
@@ -0,0 +1 @@
+export { default } from "./DatabaseCacheTimeInput";
diff --git a/enterprise/frontend/src/metabase-enterprise/caching/index.js b/enterprise/frontend/src/metabase-enterprise/caching/index.js
index a1c91a17b244bdb4a90fc74d27d740e1d267e588..599c95b2b4b4b1e845bc2dc1cda34ce8d9193602 100644
--- a/enterprise/frontend/src/metabase-enterprise/caching/index.js
+++ b/enterprise/frontend/src/metabase-enterprise/caching/index.js
@@ -5,6 +5,7 @@ import { PLUGIN_CACHING, PLUGIN_FORM_WIDGETS } from "metabase/plugins";
 import Link from "metabase/core/components/Link";
 import CacheTTLField from "./components/CacheTTLField";
 import DatabaseCacheTTLField from "./components/DatabaseCacheTTLField";
+import DatabaseCacheTimeField from "./components/DatabaseCacheTimeField";
 import QuestionCacheTTLField from "./components/QuestionCacheTTLField";
 import QuestionCacheSection from "./components/QuestionCacheSection";
 import DashboardCacheSection from "./components/DashboardCacheSection";
@@ -52,7 +53,8 @@ if (hasPremiumFeature("advanced_config")) {
   PLUGIN_FORM_WIDGETS.questionCacheTTL = QuestionCacheTTLField;
 
   PLUGIN_CACHING.getQuestionsImplicitCacheTTL = getQuestionsImplicitCacheTTL;
-  PLUGIN_CACHING.QuestionCacheSection = QuestionCacheSection;
+  PLUGIN_CACHING.DatabaseCacheTimeField = DatabaseCacheTimeField;
   PLUGIN_CACHING.DashboardCacheSection = DashboardCacheSection;
+  PLUGIN_CACHING.QuestionCacheSection = QuestionCacheSection;
   PLUGIN_CACHING.isEnabled = () => true;
 }
diff --git a/frontend/src/metabase-types/api/mocks/settings.ts b/frontend/src/metabase-types/api/mocks/settings.ts
index 36da17d91d83088b5b36dea0cfc610eef187bbbf..63fb8fe33daa7046f53d141e52252261e3bfae07 100644
--- a/frontend/src/metabase-types/api/mocks/settings.ts
+++ b/frontend/src/metabase-types/api/mocks/settings.ts
@@ -116,6 +116,7 @@ export const createMockSettings = (opts?: Partial<Settings>): Settings => ({
   "email-configured?": false,
   "enable-embedding": false,
   "enable-nested-queries": true,
+  "enable-query-caching": undefined,
   "enable-public-sharing": false,
   "enable-xrays": false,
   "experimental-enable-actions": false,
diff --git a/frontend/src/metabase-types/api/settings.ts b/frontend/src/metabase-types/api/settings.ts
index a84ae0f84cb00215ba983160d7767b5a2875f0fe..2430fbc821a1869709e172bc547e1d8fd3357938 100644
--- a/frontend/src/metabase-types/api/settings.ts
+++ b/frontend/src/metabase-types/api/settings.ts
@@ -145,6 +145,7 @@ export interface Settings {
   "embedding-secret-key"?: string;
   "enable-embedding": boolean;
   "enable-nested-queries": boolean;
+  "enable-query-caching"?: boolean;
   "enable-public-sharing": boolean;
   "enable-xrays": boolean;
   "experimental-enable-actions": boolean;
diff --git a/frontend/src/metabase-types/store/mocks/setup.ts b/frontend/src/metabase-types/store/mocks/setup.ts
index 08284538d1baeb17f55f1967211456dc50c8a07e..551d13c2c02d694b889c7cc46d31607eae677244 100644
--- a/frontend/src/metabase-types/store/mocks/setup.ts
+++ b/frontend/src/metabase-types/store/mocks/setup.ts
@@ -41,6 +41,7 @@ export const createMockDatabaseInfo = (
   schedules: {},
   auto_run_queries: false,
   refingerprint: false,
+  cache_ttl: null,
   is_sample: false,
   is_full_sync: false,
   is_on_demand: false,
diff --git a/frontend/src/metabase-types/store/setup.ts b/frontend/src/metabase-types/store/setup.ts
index e28a057403feea3bccce5c3f55ba06b2bb083ca2..51b4ac9a0936de45311e7614845d3f968c55533a 100644
--- a/frontend/src/metabase-types/store/setup.ts
+++ b/frontend/src/metabase-types/store/setup.ts
@@ -27,6 +27,7 @@ export interface DatabaseInfo {
   schedules: DatabaseSchedules;
   auto_run_queries: boolean;
   refingerprint: boolean;
+  cache_ttl: number | null;
   is_sample: boolean;
   is_full_sync: boolean;
   is_on_demand: boolean;
diff --git a/frontend/src/metabase/core/components/FormField/FormField.styled.tsx b/frontend/src/metabase/core/components/FormField/FormField.styled.tsx
index 8bd6dc89d8d317c2b9d01f68955ae9f054ecdd50..5fad9837eefc13c640ccd519d8266960e4d3edcf 100644
--- a/frontend/src/metabase/core/components/FormField/FormField.styled.tsx
+++ b/frontend/src/metabase/core/components/FormField/FormField.styled.tsx
@@ -3,31 +3,6 @@ import { color } from "metabase/lib/colors";
 import Icon from "metabase/components/Icon";
 import { FieldAlignment, FieldOrientation } from "./types";
 
-export const FieldLabelError = styled.span`
-  color: ${color("error")};
-`;
-
-export interface FieldRootProps {
-  orientation: FieldOrientation;
-  hasError: boolean;
-}
-
-export const FieldRoot = styled.div<FieldRootProps>`
-  display: ${props => props.orientation === "horizontal" && "flex"};
-  justify-content: ${props =>
-    props.orientation === "horizontal" && "space-between"};
-  color: ${props => (props.hasError ? color("error") : color("text-medium"))};
-  margin-bottom: 1.25rem;
-
-  &:focus-within {
-    color: ${color("text-medium")};
-
-    ${FieldLabelError} {
-      display: none;
-    }
-  }
-`;
-
 export interface FormCaptionProps {
   alignment: FieldAlignment;
   orientation: FieldOrientation;
@@ -44,8 +19,13 @@ export const FieldCaption = styled.div<FormCaptionProps>`
     "0.5rem"};
 `;
 
-export const FieldLabel = styled.label`
+export interface FieldLabelProps {
+  hasError: boolean;
+}
+
+export const FieldLabel = styled.label<FieldLabelProps>`
   display: block;
+  color: ${props => (props.hasError ? color("error") : color("text-medium"))};
   font-size: 0.77rem;
   font-weight: 900;
 `;
@@ -56,7 +36,12 @@ export const FieldLabelContainer = styled.div`
   margin-bottom: 0.5em;
 `;
 
+export const FieldLabelError = styled.span`
+  color: ${color("error")};
+`;
+
 export const FieldDescription = styled.div`
+  color: ${color("text-medium")};
   margin-bottom: 0.5rem;
 `;
 
@@ -77,3 +62,24 @@ export const FieldInfoLabel = styled.div`
   margin-left: auto;
   cursor: default;
 `;
+
+export interface FieldRootProps {
+  orientation: FieldOrientation;
+}
+
+export const FieldRoot = styled.div<FieldRootProps>`
+  display: ${props => props.orientation === "horizontal" && "flex"};
+  justify-content: ${props =>
+    props.orientation === "horizontal" && "space-between"};
+  margin-bottom: 1.25rem;
+
+  &:focus-within {
+    ${FieldLabel} {
+      color: ${color("text-medium")};
+    }
+
+    ${FieldLabelError} {
+      display: none;
+    }
+  }
+`;
diff --git a/frontend/src/metabase/core/components/FormField/FormField.tsx b/frontend/src/metabase/core/components/FormField/FormField.tsx
index 9e45d57a9138b1739ad7cee4f1bc20264671213c..2f918f049d782b17638b61efb81a09e8dcffed78 100644
--- a/frontend/src/metabase/core/components/FormField/FormField.tsx
+++ b/frontend/src/metabase/core/components/FormField/FormField.tsx
@@ -41,18 +41,13 @@ const FormField = forwardRef(function FormField(
   const hasError = Boolean(error);
 
   return (
-    <FieldRoot
-      {...props}
-      ref={ref}
-      orientation={orientation}
-      hasError={hasError}
-    >
+    <FieldRoot {...props} ref={ref} orientation={orientation}>
       {alignment === "start" && children}
       {(title || description) && (
         <FieldCaption alignment={alignment} orientation={orientation}>
           <FieldLabelContainer>
             {title && (
-              <FieldLabel htmlFor={htmlFor}>
+              <FieldLabel hasError={hasError} htmlFor={htmlFor}>
                 {title}
                 {hasError && <FieldLabelError>: {error}</FieldLabelError>}
               </FieldLabel>
diff --git a/frontend/src/metabase/core/utils/errors/errors.ts b/frontend/src/metabase/core/utils/errors/errors.ts
index 3f44aa8bb40da88f268b6fec7c57b6df2dd377f3..a3d08c04245e5988b37411ab747c4402406cd418 100644
--- a/frontend/src/metabase/core/utils/errors/errors.ts
+++ b/frontend/src/metabase/core/utils/errors/errors.ts
@@ -7,3 +7,5 @@ export const email = () => t`must be a valid email address`;
 
 export const maxLength = ({ max }: MaxLengthParams) =>
   t`must be ${max} characters or less`;
+
+export const positive = () => t`must be a positive integer value`;
diff --git a/frontend/src/metabase/core/utils/errors/index.ts b/frontend/src/metabase/core/utils/errors/index.ts
index 6312645f3add95b09ca44cdbc2f60f40ab8eb536..1938ef1bcff33643d47eee33012c379656fb71ba 100644
--- a/frontend/src/metabase/core/utils/errors/index.ts
+++ b/frontend/src/metabase/core/utils/errors/index.ts
@@ -1 +1 @@
-export { required, email, maxLength } from "./errors";
+export { required, email, maxLength, positive } from "./errors";
diff --git a/frontend/src/metabase/databases/components/DatabaseForm/DatabaseForm.tsx b/frontend/src/metabase/databases/components/DatabaseForm/DatabaseForm.tsx
index 3013bb1e69f9d59999a5e7a2c2c381c970049188..7df82a128be77e06d1f3b2c89e8ab246d4ad6506 100644
--- a/frontend/src/metabase/databases/components/DatabaseForm/DatabaseForm.tsx
+++ b/frontend/src/metabase/databases/components/DatabaseForm/DatabaseForm.tsx
@@ -7,6 +7,7 @@ import FormProvider from "metabase/core/components/FormProvider";
 import FormFooter from "metabase/core/components/FormFooter";
 import FormSubmitButton from "metabase/core/components/FormSubmitButton";
 import FormErrorMessage from "metabase/core/components/FormErrorMessage";
+import { PLUGIN_CACHING } from "metabase/plugins";
 import { Engine } from "metabase-types/api";
 import { DatabaseValues } from "../../types";
 import { getDefaultEngineKey } from "../../utils/engine";
@@ -22,6 +23,7 @@ export interface DatabaseFormProps {
   initialValues?: DatabaseValues;
   isHosted?: boolean;
   isAdvanced?: boolean;
+  isCachingEnabled?: boolean;
   onSubmit: (values: DatabaseValues) => void;
   onEngineChange?: (engineKey: string | undefined) => void;
   onCancel?: () => void;
@@ -32,6 +34,7 @@ const DatabaseForm = ({
   initialValues: initialData,
   isHosted = false,
   isAdvanced = false,
+  isCachingEnabled = false,
   onSubmit,
   onCancel,
   onEngineChange,
@@ -72,6 +75,7 @@ const DatabaseForm = ({
         engines={engines}
         isHosted={isHosted}
         isAdvanced={isAdvanced}
+        isCachingEnabled={isCachingEnabled}
         onEngineChange={handleEngineChange}
         onCancel={onCancel}
       />
@@ -85,6 +89,7 @@ interface DatabaseFormBodyProps {
   engines: Record<string, Engine>;
   isHosted: boolean;
   isAdvanced: boolean;
+  isCachingEnabled: boolean;
   onEngineChange: (engineKey: string | undefined) => void;
   onCancel?: () => void;
 }
@@ -95,6 +100,7 @@ const DatabaseFormBody = ({
   engines,
   isHosted,
   isAdvanced,
+  isCachingEnabled,
   onEngineChange,
   onCancel,
 }: DatabaseFormBodyProps): JSX.Element => {
@@ -122,6 +128,7 @@ const DatabaseFormBody = ({
       {fields.map(field => (
         <DatabaseDetailField key={field.name} field={field} />
       ))}
+      {isCachingEnabled && <PLUGIN_CACHING.DatabaseCacheTimeField />}
       <DatabaseFormFooter isAdvanced={isAdvanced} onCancel={onCancel} />
     </Form>
   );
diff --git a/frontend/src/metabase/databases/containers/DatabaseForm/DatabaseForm.tsx b/frontend/src/metabase/databases/containers/DatabaseForm/DatabaseForm.tsx
index 988b47982a66acda587b9ab1c7b64268192fd9c3..9ac817c781d81ed5324c93276c179a8b91e8a7c9 100644
--- a/frontend/src/metabase/databases/containers/DatabaseForm/DatabaseForm.tsx
+++ b/frontend/src/metabase/databases/containers/DatabaseForm/DatabaseForm.tsx
@@ -3,13 +3,14 @@ import { getSetting } from "metabase/selectors/settings";
 import { State } from "metabase-types/store";
 import DatabaseForm, { DatabaseFormProps } from "../../components/DatabaseForm";
 
-type DatabaseFormStateKeys = "engines" | "isHosted";
+type DatabaseFormStateKeys = "engines" | "isHosted" | "isCachingEnabled";
 type DatabaseFormOwnProps = Omit<DatabaseFormProps, DatabaseFormStateKeys>;
 type DatabaseFormStateProps = Pick<DatabaseFormProps, DatabaseFormStateKeys>;
 
 const mapStateToProps = (state: State) => ({
   engines: getSetting(state, "engines"),
   isHosted: getSetting(state, "is-hosted?"),
+  isCachingEnabled: getSetting(state, "enable-query-caching"),
 });
 
 export default connect<
diff --git a/frontend/src/metabase/databases/types.ts b/frontend/src/metabase/databases/types.ts
index c2a49942ffae6e5a4f0663307c76b666b553a368..4cd8c417bd818dbe4a3d865604320ec7fef35c48 100644
--- a/frontend/src/metabase/databases/types.ts
+++ b/frontend/src/metabase/databases/types.ts
@@ -14,6 +14,7 @@ export interface DatabaseValues {
   schedules: DatabaseSchedules;
   auto_run_queries: boolean;
   refingerprint: boolean;
+  cache_ttl: number | null;
   is_sample: boolean;
   is_full_sync: boolean;
   is_on_demand: boolean;
diff --git a/frontend/src/metabase/databases/utils/schema.ts b/frontend/src/metabase/databases/utils/schema.ts
index d3c28f8706f93cc2cad1fcac887b865e19f2df7f..43c36e9dea4359b97e4f4986ab85d3d46c57aba4 100644
--- a/frontend/src/metabase/databases/utils/schema.ts
+++ b/frontend/src/metabase/databases/utils/schema.ts
@@ -23,6 +23,7 @@ export const getValidationSchema = (
     }),
     auto_run_queries: Yup.boolean().default(true),
     refingerprint: Yup.boolean().default(false),
+    cache_ttl: Yup.number().nullable().default(null).positive(Errors.positive),
     is_sample: Yup.boolean().default(false),
     is_full_sync: Yup.boolean().default(true),
     is_on_demand: Yup.boolean().default(false),
diff --git a/frontend/src/metabase/plugins/index.ts b/frontend/src/metabase/plugins/index.ts
index 43e5ddc483d6466daa5471c9356adf4ada4857e9..92a768a04016773a3de1674703b2305e02ed4e26 100644
--- a/frontend/src/metabase/plugins/index.ts
+++ b/frontend/src/metabase/plugins/index.ts
@@ -163,6 +163,7 @@ export const PLUGIN_CACHING = {
   getQuestionsImplicitCacheTTL: (question?: any) => null,
   QuestionCacheSection: PluginPlaceholder,
   DashboardCacheSection: PluginPlaceholder,
+  DatabaseCacheTimeField: PluginPlaceholder,
   isEnabled: () => false,
 };