There are two more ways.
1) make an array of strings, limit it, and then combine into a string:
SELECT array_to_string((array_agg(tag))[1:3], ', ') FROM tbl
("array [1: 3]" means: take elements from 1 to 3 from the array)
2) concatenate the strings into a string without restrictions, then use the "substring" to crop it:
string_agg(distinct(tag),',')
If you know that the tag field cannot contain a character, then you can select all the text before the nth appearance of yours ,
SELECT substring( string_agg(DISTINCT tag, ',') from '(?:[^,]+,){1,3}') FROM tbl
This substring will select 3 or less lines divided by ,
source share