New Way:

From Go 1.10 there is a strings.Builder type, please take a look at this answer for more detail.

Old Way:

Use the bytes package. It has a Buffer type which implements io.Writer.

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var buffer bytes.Buffer

    for i := 0; i < 1000; i++ {
        buffer.WriteString("a")
    }

    fmt.Println(buffer.String())
}

This does it in O(n) time.

Answer from marketer on Stack Overflow
🌐
Go Packages
pkg.go.dev › strings
strings package - strings - Go Packages
String returns the accumulated string. ... Write appends the contents of p to b's buffer. Write always returns len(p), nil. ... WriteByte appends the byte c to b's buffer. The returned error is always nil. ... WriteRune appends the UTF-8 encoding of Unicode code point r to b's buffer. It returns the length of r and a nil error. func (b *Builder) WriteString(s string) (int, error)
Top answer
1 of 16
1095

New Way:

From Go 1.10 there is a strings.Builder type, please take a look at this answer for more detail.

Old Way:

Use the bytes package. It has a Buffer type which implements io.Writer.

package main

import (
    "bytes"
    "fmt"
)

func main() {
    var buffer bytes.Buffer

    for i := 0; i < 1000; i++ {
        buffer.WriteString("a")
    }

    fmt.Println(buffer.String())
}

This does it in O(n) time.

2 of 16
644

In Go 1.10+ there is strings.Builder, here.

A Builder is used to efficiently build a string using Write methods. It minimizes memory copying. The zero value is ready to use.


Example

It's almost the same with bytes.Buffer.

package main

import (
    "strings"
    "fmt"
)

func main() {
    // ZERO-VALUE:
    //
    // It's ready to use from the get-go.
    // You don't need to initialize it.
    var sb strings.Builder

    for i := 0; i < 1000; i++ {
        sb.WriteString("a")
    }

    fmt.Println(sb.String())
}

Click to see this on the playground.


Supported Interfaces

strings.Builder's methods are being implemented with the existing interfaces in mind so that you can switch to the new Builder type easily in your code.

Method Signature Interface Description
Grow(int) bytes.Buffer Grows the buffer's capacity by the specified amount. See bytes.Buffer#Grow for more information.
Len() int bytes.Buffer Returns the number of bytes in the buffer. See bytes.Buffer#Len for more information.
Reset() bytes.Buffer Resets the buffer to be empty. See bytes.Buffer#Reset for more information.
String() string fmt.Stringer Returns the contents of the buffer as a string. See fmt.Stringer for more information.
Write([]byte) (int, error) io.Writer Writes the given bytes to the buffer. See io.Writer for more information.
WriteByte(byte) error io.ByteWriter Writes the given byte to the buffer. See io.ByteWriter for more information.
WriteRune(rune) (int, error) bufio.Writer or bytes.Buffer Writes the given rune to the buffer. See bufio.Writer#WriteRune or bytes.Buffer#WriteRune for more information.
WriteString(string) (int, error) io.stringWriter Writes the given string to the buffer. See io.stringWriter for more information.

Differences from bytes.Buffer

  • It can only grow or reset.
  • It has a copyCheck mechanism built-in that prevents accidentally copying it. In bytes.Buffer, one can access the underlying bytes like this: (*Buffer).Bytes(). strings.Builder prevents this problem. Sometimes, this is not a problem, though, and is desired instead. For example: For the peeking behavior when the bytes are passed to an io.Reader etc.
  • bytes.Buffer.Reset() rewinds and reuses the underlying buffer whereas the strings.Builder.Reset() does not, it detaches the buffer.

Note

  • Do not copy a strings.Builder value as it caches the underlying data.
  • If you want to share a strings.Builder value, use a pointer to it.

Check out its source code for more details, here.

Discussions

strings: Copying Builders allows string mutation
I think another level of indirection is needed in the implementation, so that the internal buffer is shared even after a copy has been made More on github.com
🌐 github.com
2
December 11, 2017
proposal: strings: string transformation functions for Builder
Proposal Details There is currently no support for appending the result of any of the string transformation functions1 (Join, Replace(All)?, Repeat, Map, To(Title|Upper|Lower)(Special)?, ToValidUtf... More on github.com
🌐 github.com
1
January 29, 2024
proposal: strings/builder: strings.Builder.Set(index, byte)
However, currently there is no way to modify a specific byte in the strings.Builder after writing, such as replacing the last comma with a closing brace (}). More on github.com
🌐 github.com
2
April 7, 2025
I created a strings.Builder alternative that is more efficient
You may also on 125-126 lines consider instead of s.buf = [][]string{} s.reverseBuf = [][]string{} just resetting slice lengths to not create tasks for garbage collector immediately and also probably reuse some allocated memory s.buf = s.buf[:0] s.reverseBuf = s.reverseBuf[:0] More on reddit.com
🌐 r/golang
23
84
May 10, 2025
🌐
brandur.org
brandur.org › fragments › bytes-buffer-vs-strings-builder
Go's bytes.Buffer vs. strings.Builder — brandur.org
January 2, 2025 - $ go test -bench=. -benchmem goos: darwin goarch: arm64 pkg: github.com/brandur/go-builder-vs-buffer cpu: Apple M4 BenchmarkBytesBuffer-10 5013081 217.3 ns/op 1280 B/op 5 allocs/op BenchmarkConcatenateStrings-10 1603748 753.5 ns/op 5557 B/op 31 allocs/op BenchmarkStringBuilder-10 6916813 146.9 ns/op 752 B/op 6 allocs/op PASS ok github.com/brandur/go-builder-vs-buffer 4.724s · So there you have it. At least when it comes to concatenating only strings at relatively modest sizes, strings.Builder is about 33% faster, and 80% faster than 1 than concatenating strings.
🌐
GeeksforGeeks
geeksforgeeks.org › go language › strings-in-golang
Strings in Golang - GeeksforGeeks
March 10, 2026 - // Go program to illustrate how ... ", mystring2) } ... In Golang string, you can find the length of the string using two functions one is len() and another one is RuneCountInString()....
🌐
Boot.dev
boot.dev › blog › golang › strings-builder-concatenation-golang
Concatenating With Strings.Builder Quickly in Golang | Boot.dev
May 4, 2021 - Go 1.10+ released the awesome strings.Builder type, which lets us more efficiently build strings.
🌐
GitHub
github.com › golang › go › issues › 23084
strings: Copying Builders allows string mutation · Issue #23084 · golang/go
December 11, 2017 - This program: package main import ( "fmt" "strings" ) func main() { var b1 strings.Builder b1.Grow(3) b2 := b1 b1.WriteString("foo") s := b1.String() fmt.Printf("string before patching: %#v\n", s) b2.WriteString("bar") fmt.Printf("string...
Author   fweimer
Find elsewhere
🌐
GitHub
github.com › golang › go › issues › 65338
proposal: strings: string transformation functions for Builder · Issue #65338 · golang/go
January 29, 2024 - There is currently no support for appending the result of any of the string transformation functions1 (Join, Replace(All)?, Repeat, Map, To(Title|Upper|Lower)(Special)?, ToValidUtf8) directly to a Builder, bypassing the intermediate temporary allocation:
Author   CAFxX
🌐
Medium
medium.com › towardsdev › strings-builder-golang-88bc5a8c670f
Strings Builder — Golang
May 25, 2022 - “A Builder is used to efficiently build a string using Write methods.
🌐
Medium
medium.com › swlh › high-performance-string-building-in-go-golang-3fd99b9ca856
High-Performance String Building in Go (Golang) | by Gabriel G Baciu | The Startup | Medium
June 11, 2020 - In Golang, if you want to build a string, you’d rather need to utilize the strings.Builder type that is a subset of bytes.Buffer. Basically, Golang does not look at a string as a string per se but as a slice of bytes, where each byte is the ASCII code of the character that is in the string.
🌐
Medium
medium.com › @andreiboar › demystifying-golang-strings-05981b84f1a7
Demystifying Golang Strings. This post discusses Golang strings… | by Andrei Boar | Medium
July 15, 2024 - package main import ( "fmt" "strings" ) func main() { str := "Hello André!" str += " What a fine day!" str = str + " A fine day indeed!" var b strings.Builder b.WriteString("Hello André!") b.WriteString(" What a fine day!") fmt.Println(str) // Hello André!
🌐
DigitalOcean
digitalocean.com › community › tutorials › an-introduction-to-the-strings-package-in-go
An Introduction to the Strings Package in Go | DigitalOcean
April 30, 2019 - Go’s string package has several functions available to work with the string data type. These functions let us easily modify and manipulate strings. We can think of functions as being actions that we perform on elements of our code.
🌐
GitHub
github.com › golang › go › issues › 73189
proposal: strings/builder: strings.Builder.Set(index, byte) · Issue #73189 · golang/go
April 7, 2025 - Proposal Details // Set[T] map set type Set[T comparable] map[T]struct{} func (s Set[T]) String() string { n := len(s) if n == 0 { return "{}" } if n == 1 { for elem := range s { return fmt.Sprintf("{%v}", elem) } } var b []byte b = appe...
Author   wangzhione
🌐
Go Packages
pkg.go.dev › github.com › linkdotnet › golang-stringbuilder
Text package - github.com/linkdotnet/golang-stringbuilder - Go Packages
October 20, 2023 - A string builder that has similar capabilities as the one from C#. The goal is to have a straightforward API that lets you work with strings easily.
🌐
Reddit
reddit.com › r/golang › i created a strings.builder alternative that is more efficient
r/golang on Reddit: I created a strings.Builder alternative that is more efficient
May 10, 2025 - r/golang • · upvotes · · comments · New in Go 1.10: strings.Builder - Efficiently build string with minimized memory allocations · r/golang • · upvotes · · comments · Need an alternative to Airtable · r/Airtable • · upvotes · · comments · Can someone give me a simple explanation of the point of structs and interfaces, and what they do?
🌐
GitHub
github.com › nasa9084 › go-builderpool
GitHub - nasa9084/go-builderpool: A simple strings.Builder pool using sync.Pool
A simple strings.Builder pool using sync.Pool inspired by lestrrat-go/bufferpool.
Author   nasa9084
🌐
Go Forum
forum.golangbridge.org › getting help
Dynamically Build Strings - Getting Help - Go Forum
April 30, 2020 - Hello All, I was wondering how I would approach dynamically building strings based on a length of slice. Link to playground with starting slice and what the final string should look like. https://play.golang.org/p/zT153jeIZBF The length and values of the string will change based on user input.
🌐
ZetCode
zetcode.com › golang › builder
Efficient String Manipulation with strings.Builder in Go
April 11, 2025 - In this article we show how to build strings efficiently in Golang with strings.Builder.