Create custom table with pagination
Here is an example of sortable table with pagination.

$header = [
  'id' =&gt; [
    'data' =&gt; $this-&gt;t('ID'),
    'specifier' =&gt; 'nid',
  ],
  'title' =&gt; [
    'data' =&gt; $this-&gt;t('Title'),
    'specifier' =&gt; 'title',
  ],
  'created' =&gt; [
    'data' =&gt; $this-&gt;t('Created'),
    'specifier' =&gt; 'created',
    // Set default sort criteria.
    'sort' =&gt; 'desc',
  ],
  'uid' =&gt; [
    'data' =&gt; $this-&gt;t('Author'),
    'specifier' =&gt; 'uid',
  ],
];

$storage = \Drupal::entityTypeManager()-&gt;getStorage('node');

$query = $storage-&gt;getQuery();
$query-&gt;condition('status', \Drupal\node\NodeInterface::PUBLISHED);
$query-&gt;condition('type', 'article');
$query-&gt;tableSort($header);
// Default value is 10.
$query-&gt;pager(15);
$nids = $query-&gt;execute();

$date_formatter = \Drupal::service('date.formatter');
$rows = [];
foreach ($storage-&gt;loadMultiple($nids) as $node) {
  $row = [];
  $row[] = $node-&gt;id();
  $row[] = $node-&gt;toLink();
  $created = $node-&gt;get('created')-&gt;value;
  $row[] = [
    'data' =&gt; [
      '#theme' =&gt; 'time',
      '#text' =&gt; $date_formatter-&gt;format($created),
      '#attributes' =&gt; [
        'datetime' =&gt; $date_formatter-&gt;format($created, 'custom', \DateTime::RFC3339),
      ],
    ],
  ];
  $row[] = [
    'data' =&gt; $node-&gt;get('uid')-&gt;view(),
  ];
  $rows[] = $row;
}

$build['table'] = [
  '#type' =&gt; 'table',
  '#header' =&gt; $header,
  '#rows' =&gt; $rows,
  '#empty' =&gt; $this-&gt;t('No content has been found.'),
];

$build['pager'] = [
  '#type' =&gt; 'pager',
];