diff --git a/buildkite/tools/pipelinestats/main.go b/buildkite/tools/pipelinestats/main.go
new file mode 100644
index 0000000..5d417b3
--- /dev/null
+++ b/buildkite/tools/pipelinestats/main.go
@@ -0,0 +1,243 @@
+package main
+
+import (
+	"encoding/csv"
+	"flag"
+	"fmt"
+	"os"
+	"sort"
+	"strconv"
+	"time"
+
+	"github.com/buildkite/go-buildkite/buildkite"
+)
+
+type durationPercentiles struct {
+	Max   time.Duration
+	Min   time.Duration
+	Pct90 time.Duration
+	Pct70 time.Duration
+	Pct50 time.Duration
+	Pct30 time.Duration
+}
+
+type dayBuildStats struct {
+	Day          time.Time
+	NumBuilds    int
+	NumFailed    int
+	NumPassed    int
+	BuildTimes   durationPercentiles
+	JobWaitTimes map[string]durationPercentiles
+}
+
+func optionsForPage(page int) *buildkite.BuildsListOptions {
+	return &buildkite.BuildsListOptions{
+		ListOptions: buildkite.ListOptions{
+			Page:    page,
+			PerPage: 100,
+		},
+	}
+}
+
+func fetchAllBuilds(org string, pipeline string, client *buildkite.Client) ([]buildkite.Build, error) {
+	page := 0
+	var builds []buildkite.Build
+	for {
+		buildsOnPage, _, err := client.Builds.ListByPipeline(org, pipeline, optionsForPage(page))
+		if err != nil {
+			return nil, err
+		}
+		if len(buildsOnPage) == 0 {
+			break
+		}
+		builds = append(builds, buildsOnPage...)
+		page++
+	}
+	return builds, nil
+}
+
+func computeDurationPercentiles(durations []time.Duration) durationPercentiles {
+	if len(durations) == 0 {
+		return durationPercentiles{}
+	}
+
+	sort.Slice(durations, func(i, j int) bool {
+		return durations[i] < durations[j]
+	})
+
+	return durationPercentiles{
+		Max:   durations[len(durations)-1],
+		Min:   durations[0],
+		Pct90: durations[9*len(durations)/10],
+		Pct70: durations[7*len(durations)/10],
+		Pct50: durations[5*len(durations)/10],
+		Pct30: durations[3*len(durations)/10],
+	}
+}
+
+func computeDayBuildStats(builds []buildkite.Build) *dayBuildStats {
+	if len(builds) == 0 {
+		return nil
+	}
+	var stats dayBuildStats
+	createdAt := builds[0].CreatedAt
+	stats.Day = time.Date(createdAt.Year(), createdAt.Month(), createdAt.Day(), 0, 0, 0, 0,
+		createdAt.Location())
+	stats.NumBuilds = len(builds)
+
+	var buildTimes []time.Duration
+	jobWaitTimes := make(map[string][]time.Duration)
+	for _, build := range builds {
+		if build.FinishedAt != nil && build.CreatedAt != nil {
+			buildTime := time.Duration(0)
+			for _, job := range build.Jobs {
+				if job.Name == nil || job.StartedAt == nil || job.CreatedAt == nil ||
+					job.FinishedAt == nil {
+					continue
+				}
+				waitTime := job.StartedAt.Time.Sub(job.CreatedAt.Time)
+				jobBuildTime := job.FinishedAt.Time.Sub(job.StartedAt.Time)
+				if jobBuildTime > buildTime {
+					// Use the maximum job build time as the duration, instead of the build's
+					// start and finish time. This is because retries of jobs also count towards
+					// the build's time.
+					buildTime = jobBuildTime
+				}
+				jobWaitTimes[*job.Name] = append(jobWaitTimes[*job.Name], waitTime)
+			}
+			buildTimes = append(buildTimes, buildTime)
+		}
+
+		if *build.State == "passed" {
+			stats.NumPassed++
+		}
+		if *build.State == "failed" {
+			stats.NumFailed++
+		}
+	}
+
+	stats.BuildTimes = computeDurationPercentiles(buildTimes)
+
+	stats.JobWaitTimes = make(map[string]durationPercentiles, len(jobWaitTimes))
+	for jobName, durations := range jobWaitTimes {
+		stats.JobWaitTimes[jobName] = computeDurationPercentiles(durations)
+	}
+
+	return &stats
+}
+
+func buildStatsPerDay(builds []buildkite.Build) ([]*dayBuildStats, []string) {
+	if len(builds) == 0 {
+		return []*dayBuildStats{}, []string{}
+	}
+
+	sort.Slice(builds, func(i, j int) bool {
+		return builds[i].CreatedAt.Time.Before(builds[j].CreatedAt.Time)
+	})
+
+	var stats []*dayBuildStats
+	day := 0
+	var dayBuilds []buildkite.Build
+	jobNamesMap := make(map[string]bool)
+	for _, build := range builds {
+		if day != build.CreatedAt.Day() {
+			if len(dayBuilds) > 0 {
+				dayStats := computeDayBuildStats(dayBuilds)
+				for jobName := range dayStats.JobWaitTimes {
+					jobNamesMap[jobName] = true
+				}
+				stats = append(stats, dayStats)
+			}
+
+			dayBuilds = nil
+			day = build.CreatedAt.Day()
+		}
+		dayBuilds = append(dayBuilds, build)
+	}
+
+	if len(dayBuilds) > 0 {
+		dayStats := computeDayBuildStats(dayBuilds)
+		for jobName := range dayStats.JobWaitTimes {
+			jobNamesMap[jobName] = true
+		}
+		stats = append(stats, dayStats)
+
+	}
+
+	var jobNames []string
+	for jobName := range jobNamesMap {
+		jobNames = append(jobNames, jobName)
+	}
+	sort.Strings(jobNames)
+
+	return stats, jobNames
+}
+
+func durationPercentilesFieldNames(prefix string) []string {
+	fieldNames := []string{"Max", "Min", "Pct90", "Pc70", "Pct50", "Pct30"}
+	for i, value := range fieldNames {
+		fieldNames[i] = prefix + "." + value
+	}
+	return fieldNames
+}
+
+func appendDurationPercentiles(line []string, stats *durationPercentiles) []string {
+	line = append(line, strconv.Itoa(int(stats.Max.Seconds())))
+	line = append(line, strconv.Itoa(int(stats.Min.Seconds())))
+	line = append(line, strconv.Itoa(int(stats.Pct90.Seconds())))
+	line = append(line, strconv.Itoa(int(stats.Pct70.Seconds())))
+	line = append(line, strconv.Itoa(int(stats.Pct50.Seconds())))
+	line = append(line, strconv.Itoa(int(stats.Pct30.Seconds())))
+
+	return line
+}
+
+func main() {
+	apiToken := os.Getenv("BUILDKITE_API_TOKEN")
+	if apiToken == "" {
+		fmt.Println("BUILDKITE_API_TOKEN environment variable not set.")
+		os.Exit(1)
+	}
+	pipelineSlug := flag.String("pipeline_slug", "", "Slug of the Buildkite pipeline")
+	flag.Parse()
+
+	if *pipelineSlug == "" {
+		flag.Usage()
+		os.Exit(1)
+	}
+
+	config, _ := buildkite.NewTokenConfig(apiToken, false)
+	client := buildkite.NewClient(config.Client())
+
+	builds, _ := fetchAllBuilds("bazel", *pipelineSlug, client)
+	stats, jobNames := buildStatsPerDay(builds)
+
+	writer := csv.NewWriter(os.Stdout)
+	defer writer.Flush()
+
+	csvHeaders := []string{"Day", "NumBuilds", "NumFailed", "NumPassed"}
+	csvHeaders = append(csvHeaders, durationPercentilesFieldNames("BuildTimes")...)
+	for _, jobName := range jobNames {
+		csvHeaders = append(csvHeaders, durationPercentilesFieldNames("WaitTimes["+jobName+"]")...)
+	}
+	writer.Write(csvHeaders)
+
+	for _, dayStats := range stats {
+		var line []string
+		line = append(line, dayStats.Day.Format("2006-01-02"))
+		line = append(line, strconv.Itoa(dayStats.NumBuilds))
+		line = append(line, strconv.Itoa(dayStats.NumFailed))
+		line = append(line, strconv.Itoa(dayStats.NumPassed))
+
+		line = appendDurationPercentiles(line, &dayStats.BuildTimes)
+
+		for _, jobName := range jobNames {
+			if waitTimes, ok := dayStats.JobWaitTimes[jobName]; ok {
+				line = appendDurationPercentiles(line, &waitTimes)
+			} else {
+				line = appendDurationPercentiles(line, &durationPercentiles{})
+			}
+		}
+		writer.Write(line)
+	}
+}
