diff --git a/packages/console/src/pages/ApiResources/index.module.scss b/packages/console/src/pages/ApiResources/index.module.scss
index 1122ae523..43664e39b 100644
--- a/packages/console/src/pages/ApiResources/index.module.scss
+++ b/packages/console/src/pages/ApiResources/index.module.scss
@@ -14,6 +14,10 @@
   flex: 1;
 }
 
+.pagination {
+  min-height: 64px;
+}
+
 .apiResourceName {
   width: 360px;
 }
diff --git a/packages/console/src/pages/ApiResources/index.tsx b/packages/console/src/pages/ApiResources/index.tsx
index c5c5e5e28..d11510b45 100644
--- a/packages/console/src/pages/ApiResources/index.tsx
+++ b/packages/console/src/pages/ApiResources/index.tsx
@@ -1,11 +1,10 @@
 import { Resource } from '@logto/schemas';
-import { conditional } from '@silverhand/essentials/lib/utilities/conditional.js';
 import classNames from 'classnames';
 import React, { useState } from 'react';
 import { toast } from 'react-hot-toast';
 import { useTranslation } from 'react-i18next';
 import Modal from 'react-modal';
-import { useNavigate } from 'react-router-dom';
+import { useNavigate, useSearchParams } from 'react-router-dom';
 import useSWR from 'swr';
 
 import Button from '@/components/Button';
@@ -14,6 +13,7 @@ import CardTitle from '@/components/CardTitle';
 import CopyToClipboard from '@/components/CopyToClipboard';
 import ImagePlaceholder from '@/components/ImagePlaceholder';
 import ItemPreview from '@/components/ItemPreview';
+import Pagination from '@/components/Pagination';
 import TableEmpty from '@/components/Table/TableEmpty';
 import TableError from '@/components/Table/TableError';
 import TableLoading from '@/components/Table/TableLoading';
@@ -26,12 +26,19 @@ import * as styles from './index.module.scss';
 
 const buildDetailsLink = (id: string) => `/api-resources/${id}`;
 
+const pageSize = 20;
+
 const ApiResources = () => {
   const [isCreateFormOpen, setIsCreateFormOpen] = useState(false);
   const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
-  const { data, error, mutate } = useSWR<Resource[], RequestError>('/api/resources');
+  const [query, setQuery] = useSearchParams();
+  const pageIndex = Number(query.get('page') ?? '1');
+  const { data, error, mutate } = useSWR<[Resource[], number], RequestError>(
+    `/api/resources?page=${pageIndex}&page_size=${pageSize}`
+  );
   const isLoading = !data && !error;
   const navigate = useNavigate();
+  const [apiResources, totalCount] = data ?? [];
 
   return (
     <Card className={styles.card}>
@@ -54,7 +61,6 @@ const ApiResources = () => {
               setIsCreateFormOpen(false);
 
               if (createdApiResource) {
-                void mutate(conditional(data && [...data, createdApiResource]));
                 toast.success(
                   t('api_resources.api_resource_created', { name: createdApiResource.name })
                 );
@@ -85,7 +91,7 @@ const ApiResources = () => {
               />
             )}
             {isLoading && <TableLoading columns={2} />}
-            {data?.length === 0 && (
+            {apiResources?.length === 0 && (
               <TableEmpty columns={2}>
                 <Button
                   title="admin_console.api_resources.create"
@@ -96,7 +102,7 @@ const ApiResources = () => {
                 />
               </TableEmpty>
             )}
-            {data?.map(({ id, name, indicator }) => (
+            {apiResources?.map(({ id, name, indicator }) => (
               <tr
                 key={id}
                 className={tableStyles.clickable}
@@ -115,6 +121,17 @@ const ApiResources = () => {
           </tbody>
         </table>
       </div>
+      <div className={styles.pagination}>
+        {!!totalCount && (
+          <Pagination
+            pageCount={Math.ceil(totalCount / pageSize)}
+            pageIndex={pageIndex}
+            onChange={(page) => {
+              setQuery({ page: String(page) });
+            }}
+          />
+        )}
+      </div>
     </Card>
   );
 };
diff --git a/packages/console/src/pages/Applications/index.module.scss b/packages/console/src/pages/Applications/index.module.scss
index e1e6c4560..3f0ea711c 100644
--- a/packages/console/src/pages/Applications/index.module.scss
+++ b/packages/console/src/pages/Applications/index.module.scss
@@ -14,6 +14,10 @@
   flex: 1;
 }
 
+.pagination {
+  min-height: 64px;
+}
+
 .applicationName {
   width: 360px;
 }
diff --git a/packages/console/src/pages/Applications/index.tsx b/packages/console/src/pages/Applications/index.tsx
index 47a0c9938..2c5c2bd34 100644
--- a/packages/console/src/pages/Applications/index.tsx
+++ b/packages/console/src/pages/Applications/index.tsx
@@ -1,11 +1,10 @@
 import { Application } from '@logto/schemas';
-import { conditional } from '@silverhand/essentials/lib/utilities/conditional.js';
 import classNames from 'classnames';
 import React, { useState } from 'react';
 import { toast } from 'react-hot-toast';
 import { useTranslation } from 'react-i18next';
 import Modal from 'react-modal';
-import { useNavigate } from 'react-router-dom';
+import { useNavigate, useSearchParams } from 'react-router-dom';
 import useSWR from 'swr';
 
 import Button from '@/components/Button';
@@ -14,6 +13,7 @@ import CardTitle from '@/components/CardTitle';
 import CopyToClipboard from '@/components/CopyToClipboard';
 import ImagePlaceholder from '@/components/ImagePlaceholder';
 import ItemPreview from '@/components/ItemPreview';
+import Pagination from '@/components/Pagination';
 import TableEmpty from '@/components/Table/TableEmpty';
 import TableError from '@/components/Table/TableError';
 import TableLoading from '@/components/Table/TableLoading';
@@ -25,12 +25,19 @@ import { applicationTypeI18nKey } from '@/types/applications';
 import CreateForm from './components/CreateForm';
 import * as styles from './index.module.scss';
 
+const pageSize = 20;
+
 const Applications = () => {
   const [isCreateFormOpen, setIsCreateFormOpen] = useState(false);
   const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
-  const { data, error, mutate } = useSWR<Application[], RequestError>('/api/applications');
+  const [query, setQuery] = useSearchParams();
+  const pageIndex = Number(query.get('page') ?? '1');
+  const { data, error, mutate } = useSWR<[Application[], number], RequestError>(
+    `/api/applications?page=${pageIndex}&page_size=${pageSize}`
+  );
   const isLoading = !data && !error;
   const navigate = useNavigate();
+  const [applications, totalCount] = data ?? [];
 
   return (
     <Card className={styles.card}>
@@ -53,8 +60,6 @@ const Applications = () => {
               setIsCreateFormOpen(false);
 
               if (createdApp) {
-                void mutate(conditional(data && [...data, createdApp]));
-
                 toast.success(t('applications.application_created', { name: createdApp.name }));
                 navigate(`/applications/${createdApp.id}`);
               }
@@ -83,7 +88,7 @@ const Applications = () => {
               />
             )}
             {isLoading && <TableLoading columns={2} />}
-            {data?.length === 0 && (
+            {applications?.length === 0 && (
               <TableEmpty columns={2}>
                 <Button
                   title="admin_console.applications.create"
@@ -94,7 +99,7 @@ const Applications = () => {
                 />
               </TableEmpty>
             )}
-            {data?.map(({ id, name, type }) => (
+            {applications?.map(({ id, name, type }) => (
               <tr
                 key={id}
                 className={tableStyles.clickable}
@@ -118,6 +123,17 @@ const Applications = () => {
           </tbody>
         </table>
       </div>
+      <div className={styles.pagination}>
+        {!!totalCount && (
+          <Pagination
+            pageCount={Math.ceil(totalCount / pageSize)}
+            pageIndex={pageIndex}
+            onChange={(page) => {
+              setQuery({ page: String(page) });
+            }}
+          />
+        )}
+      </div>
     </Card>
   );
 };
diff --git a/packages/console/src/pages/Users/index.tsx b/packages/console/src/pages/Users/index.tsx
index 3355273dd..da19666f1 100644
--- a/packages/console/src/pages/Users/index.tsx
+++ b/packages/console/src/pages/Users/index.tsx
@@ -135,7 +135,7 @@ const Users = () => {
         </table>
       </div>
       <div className={styles.pagination}>
-        {totalCount !== undefined && totalCount > 0 && (
+        {!!totalCount && (
           <Pagination
             pageCount={Math.ceil(totalCount / pageSize)}
             pageIndex={pageIndex}