Run Github Actions Within Monthly Limit

Run Github Actions Within Monthly Limit
Photo by Headway on Unsplash

Suppose you are using Github free plan, you are running actions in your private repo and keep exceeding the monthly minutes limit, then this article is going to help you to make optimized usage of the actions minutes in step by step manner.

Step one: run workflow on schedule instead of push

Rather than running the workflow on every push, you can run it in a periodic manner. For example, you can define schedule in workflow yml file:

name: Your Action
    - cron: "0 8-18 * * *"

Then the workflow will be triggered every day from 8am to 6pm at every hour. So from infinite amount of runs, we are reducing it to roughly 300 times a month. If it requires 10 minutes per workflow, then total minutes will be 3000, which is more than 2000 free minutes 😄.

Step two: run workflow manually only if you push

Our next step is to run the workflow only if there has been a push in the repo. We do not want to run the workflow in an unchanged codebase every hour. To do that, let us follow these steps:

1. First change the existing workflow to be only triggered if there is a manual dispatch request to that workflow:

name: Your Action
      - build_application

2. Create a script which will trigger the main workflow if there is a push within last hour:

import os
import datetime
import time
from git import Repo
import requests

repo = Repo('.')
headcommit = repo.head.commit
commit_date = time.gmtime(headcommit.committed_date)
today = datetime.datetime.utcnow()
if (commit_date.tm_year, commit_date.tm_mon, commit_date.tm_mday, commit_date.tm_hour )  \
     == (today.year, today.month,, today.hour - 1): 
    headers = {
        'Accept': 'application/vnd.github.everest-preview+json',
        'Content-Type': 'application/json',

    data = '{"event_type": "build_application"}'

    USERNAME = os.environ.get('PAT_USERNAME')  # will discuss more later
    TOKEN = os.environ.get('TOKEN')  # will discuss more later
    REPO = os.environ.get('REPO')  # will discuss more later
    response =
        '{}/{}/dispatches'.format(USERNAME, REPO),
        headers=headers, data=data, auth=(
    print(response.status_code, response.content)
    print('No commit')

3. Let us create another actions yml file inside .github/workflows directory which will run the script above at every hour:

name: Trigger Main Workflow
    - cron: "0 * * * *"
    runs-on: ubuntu-18.04
      - name: Git checkout
        uses: actions/checkout@v1

      - name: Setup python
        uses: actions/setup-python@v1
          python-version: "3.x"
          architecture: "x64"

      - name: Install dependencies
        run: pip install gitpython requests

      - name: Run scheduled task
          REPO: ${{ secrets.REPO }}
          PAT_USERNAME: ${{ secrets.PAT_USERNAME }}
          TOKEN: ${{ secrets.TOKEN }}
        run: python

To be clear, this workflow will run everyday for once every hour. It takes 23-27 seconds on average.

4. Create a Personal access token from Click on Generate new token button, provide a name and select workflow checkbox. Then click Generate token and copy this token to a safe place.

5. Finally, add three environment PAT_USERNAME, TOKEN, REPO variables in <Your Repo> -> Settings -> Secrets -> Actions. PAT_USERNAME is your username for GitHub, TOKEN is the Personal access token you have generated in previous step, REPO is the current repo name where you want to run the actions.


Commit everything and push to your repo, and voilà ⚡!! your main workflow will run every hour only if there is a push in the last hour.

In conclusion

In this article we discussed how you can reduce the number of times you run your workflow for your private repository. Hope it helps. Cheers!!

Last updated: May 22, 2024

← Previous
Serverless and Actions

Make your JAMStack more interactive with applications deployed using Serverless and Actions.

Next →
Journey to Vim

Take your productivity to the next level using Vim, a text editor. All it takes is a leap of faith.

Share Your Thoughts
M↓ Markdown